> getUserHistoryDtos(@RequestBody PausedUserHistoryRo userHistoryRo) {
- LocalDateTime now = LocalDateTime.now();
+ LocalDateTime now = ClockManager.me().getLocalDateTimeNow();
LocalDateTime createdBefore = now.minusDays(30 + userHistoryRo.getLimitDays());
// LocalDateTime createdAfter = now.minusDays(lastDays);
// After obtaining the specified cooling-off period, there has been an operation to cancel the application within 30 days before.
diff --git a/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceSubscriptionVo.java b/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceSubscriptionVo.java
index bb3e82e1c62190c09d79eb9dc68d668a22fd72df..5cd718ff2f9539c2b7d855aeb48de53c3c654831 100644
--- a/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceSubscriptionVo.java
+++ b/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceSubscriptionVo.java
@@ -57,7 +57,7 @@ public class InternalSpaceSubscriptionVo {
@JsonSerialize(nullsUsing = NullNumberSerializer.class)
private Long maxCalendarViewsInSpace;
- @ApiModelProperty(value = "Is it possible to call enterprise-level APIs", example = "true", position = 7)
+ @ApiModelProperty(value = "allow use embed", example = "true", position = 7)
@JsonSerialize(nullsUsing = NullBooleanSerializer.class)
- private Boolean canCallEnterpriseApi;
+ private Boolean allowEmbed;
}
diff --git a/backend-server/application/src/main/java/com/apitable/player/dto/PlayerBaseDTO.java b/backend-server/application/src/main/java/com/apitable/player/dto/PlayerBaseDTO.java
index c6e199ea2555e43299a6ce37cd0dafae24ef8ded..5c19f3cd8aeaabfb8f83337a4f61846c86e713b9 100644
--- a/backend-server/application/src/main/java/com/apitable/player/dto/PlayerBaseDTO.java
+++ b/backend-server/application/src/main/java/com/apitable/player/dto/PlayerBaseDTO.java
@@ -32,6 +32,10 @@ public class PlayerBaseDTO {
private String avatar;
+ private Integer color;
+
+ private String nickName;
+
private String team;
private Boolean isNickNameModified;
diff --git a/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java b/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java
index 49662031e92a58f09d3a894fdd944986b7526487..c79a06daf19bd1fe446815c8d20be722b4497218 100644
--- a/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java
+++ b/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java
@@ -18,22 +18,6 @@
package com.apitable.player.service.impl;
-import java.io.IOException;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
@@ -45,20 +29,14 @@ import cn.hutool.core.lang.Dict;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.net.url.UrlPath;
import cn.hutool.core.net.url.UrlQuery;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.CharsetUtil;
-import cn.hutool.core.util.NumberUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.*;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-import com.baomidou.mybatisplus.core.toolkit.IdWorker;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.cursor.Cursor;
-
+import com.apitable.core.constants.RedisConstants;
+import com.apitable.core.exception.BusinessException;
+import com.apitable.core.util.ExceptionUtil;
+import com.apitable.core.util.SpringContextHolder;
import com.apitable.organization.service.IMemberService;
import com.apitable.organization.service.IUnitService;
import com.apitable.player.dto.NotificationModelDTO;
@@ -76,12 +54,7 @@ import com.apitable.player.vo.PlayerBaseVo;
import com.apitable.shared.cache.bean.LoginUserDto;
import com.apitable.shared.component.ClientEntryTemplateConfig;
import com.apitable.shared.component.TaskManager;
-import com.apitable.shared.component.notification.INotificationFactory;
-import com.apitable.shared.component.notification.NotificationHelper;
-import com.apitable.shared.component.notification.NotificationRenderMap;
-import com.apitable.shared.component.notification.NotificationTemplateId;
-import com.apitable.shared.component.notification.NotificationToTag;
-import com.apitable.shared.component.notification.NotifyMailFactory;
+import com.apitable.shared.component.notification.*;
import com.apitable.shared.component.notification.NotifyMailFactory.MailWithLang;
import com.apitable.shared.config.properties.ConstProperties;
import com.apitable.shared.constants.NotificationConstants;
@@ -96,29 +69,28 @@ import com.apitable.user.dto.UserLangDTO;
import com.apitable.user.mapper.UserMapper;
import com.apitable.user.service.IUserService;
import com.apitable.workspace.service.INodeService;
-import com.apitable.core.constants.RedisConstants;
-import com.apitable.core.exception.BusinessException;
-import com.apitable.core.util.ExceptionUtil;
-import com.apitable.core.util.SpringContextHolder;
-
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.cursor.Cursor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_MINUTE_PATTERN;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_CONTACT_URL;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_CREATED_AT;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_DATASHEET_URL;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_MEMBER_NAME;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_NODE_NAME;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_RECORD_ID;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_RECORD_URL;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_SPACE_NAME;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_URL;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_VIEW_ID;
-import static com.apitable.shared.constants.NotificationConstants.EXPIRE_AT;
-import static com.apitable.shared.constants.NotificationConstants.INVOLVE_RECORD_IDS;
+import static com.apitable.shared.constants.NotificationConstants.*;
/**
*
diff --git a/backend-server/application/src/main/java/com/apitable/player/vo/PlayerBaseVo.java b/backend-server/application/src/main/java/com/apitable/player/vo/PlayerBaseVo.java
index 3b0d8d67ba0b44632660bbdba786f649ed5fa67a..e95308691b99dc8ba1556f0d559a73baa9e2b109 100644
--- a/backend-server/application/src/main/java/com/apitable/player/vo/PlayerBaseVo.java
+++ b/backend-server/application/src/main/java/com/apitable/player/vo/PlayerBaseVo.java
@@ -18,6 +18,9 @@
package com.apitable.player.vo;
+import com.apitable.shared.support.serializer.ImageSerializer;
+import com.apitable.shared.support.serializer.NullBooleanSerializer;
+import com.apitable.shared.support.serializer.NullStringSerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
@@ -25,10 +28,6 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
-import com.apitable.shared.support.serializer.ImageSerializer;
-import com.apitable.shared.support.serializer.NullBooleanSerializer;
-import com.apitable.shared.support.serializer.NullStringSerializer;
-
/**
*
* Basic user information
@@ -80,4 +79,12 @@ public class PlayerBaseVo {
@ApiModelProperty(value = "User player type 1: members in the space have not been removed, 2 members outside the space have been removed, and 3 visitors (non space registered users)", example = "1")
private Integer playerType;
+
+ @ApiModelProperty(value = "default avatar color number", example = "1")
+ @JsonSerialize(nullsUsing = NullStringSerializer.class)
+ private Integer avatarColor;
+
+ @ApiModelProperty(value = "Nick Name", example = "Zhang San")
+ @JsonSerialize(nullsUsing = NullStringSerializer.class)
+ private String nickName;
}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/captcha/email/TencentMailTemplate.java b/backend-server/application/src/main/java/com/apitable/shared/captcha/email/TencentMailTemplate.java
deleted file mode 100644
index 58661e4f1f6234a54291aae5eb39a7ec13108345..0000000000000000000000000000000000000000
--- a/backend-server/application/src/main/java/com/apitable/shared/captcha/email/TencentMailTemplate.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * APITable
- * Copyright (C) 2022 APITable Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package com.apitable.shared.captcha.email;
-
-import java.util.Locale;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_ADD_RECORD_LIMITED;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_ADD_RECORD_SOON_LIMITED;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_CAPACITY_FULL;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_CHANGE_ADMIN;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_DATASHEET_REMIND;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_INVITE_NOTIFY;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_PAI_SUCCESS;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_RECORD_COMMENT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_REGISTER;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_REMOVE_MEMBER;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SPACE_APPLY;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_ADMIN_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_API_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_CALENDAR_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_CAPACITY_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_DATASHEET_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_DATASHEET_RECORD_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_FIELD_PERMISSION_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_FILE_PERMISSION_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_FORM_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_GANNT_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_MIRROR_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_RECORD_CELL_UPDATED;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_RECORD_COMMENTED;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_RECORD_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_SUBSCRIBED_SEATS_LIMIT;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_TASK_REMINDER;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_VERIFY_CODE;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WARN_NOTIFY;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_QUALIFICATION_AUTH_FAIL;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_QUALIFICATION_AUTH_SUCCESS;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_SUBMIT_FAIL;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_SUBMIT_SUCCESS;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_TRANSFER_NOTIFY;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_UNPUBLISH_GLOBAL_NOTIFY;
-import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_UNPUBLISH_NOTIFY;
-
-/**
- *
- * tencent cloud email template
- *
- *
- * @author Chambers
- */
-public class TencentMailTemplate {
-
- public static Long getTemplateId(String lang, String subject) {
- if (Locale.US.toLanguageTag().equals(lang)) {
- return USMailTemplate.getTemplateIdBySubject(subject);
- }
- return ChineseMailTemplate.getTemplateIdBySubject(subject);
- }
-
-
- @AllArgsConstructor
- @Getter
- public enum ChineseMailTemplate {
-
- /**
- * email verification code
- */
- VERIFY_CODE(SUBJECT_VERIFY_CODE, 27395L),
-
- /**
- * primary admin transfer notification
- */
- CHANGE_ADMIN(SUBJECT_CHANGE_ADMIN, 26507L),
-
- /**
- * payment successful
- */
- PAI_SUCCESS(SUBJECT_PAI_SUCCESS, 23462L),
-
- /**
- * registration verification code
- */
- REGISTER(SUBJECT_REGISTER, 27395L),
-
- /**
- * space invitation notice
- */
- INVITE_NOTIFY(SUBJECT_INVITE_NOTIFY, 26497L),
-
- /**
- * Notice that the space capacity has reached the upper limit
- */
- CAPACITY_FULL(SUBJECT_CAPACITY_FULL, 23465L),
-
- /**
- * log comment mentions
- */
- RECORD_COMMENT(SUBJECT_RECORD_COMMENT, 23466L),
-
- /**
- * member field notification
- */
- DATASHEET_REMIND(SUBJECT_DATASHEET_REMIND, 23467L),
-
- /**
- * transfer of mini program publishing rights
- */
- WIDGET_TRANSFER_NOTIFY(SUBJECT_WIDGET_TRANSFER_NOTIFY, 23468L),
-
- /**
- * small program takedown notice
- */
- WIDGET_UNPUBLISH_NOTIFY(SUBJECT_WIDGET_UNPUBLISH_NOTIFY, 23469L),
-
- /**
- * space station join application
- */
- SPACE_APPLY(SUBJECT_SPACE_APPLY, 26509L),
-
- /**
- * move out of space station notification
- */
- REMOVE_MEMBER(SUBJECT_REMOVE_MEMBER, 23471L),
-
- /**
- * alert email
- */
- WARN_NOTIFY(SUBJECT_WARN_NOTIFY, 23533L),
-
- /**
- * adding records is about to exceed the limit
- */
- ADD_RECORD_SOON_LIMITED(SUBJECT_ADD_RECORD_SOON_LIMITED, 23956L),
-
- /**
- * add record overrun
- */
- ADD_RECORD_LIMITED(SUBJECT_ADD_RECORD_LIMITED, 24007L),
-
- /**
- * the applet was successfully launched
- */
- WIDGET_SUBMIT_SUCCESS(SUBJECT_WIDGET_SUBMIT_SUCCESS, 24533L),
-
- /**
- * failed to launch the applet
- */
- WIDGET_SUBMIT_FAIL(SUBJECT_WIDGET_SUBMIT_FAIL, 24534L),
-
- /**
- * Mini Program Developer Qualification Certification Successfully
- */
- WIDGET_QUALIFICATION_AUTH_SUCCESS(SUBJECT_WIDGET_QUALIFICATION_AUTH_SUCCESS, 24532L),
-
- /**
- * The qualification authentication of the Mini Program developer failed
- */
- WIDGET_QUALIFICATION_AUTH_FAIL(SUBJECT_WIDGET_QUALIFICATION_AUTH_FAIL, 24531L),
-
- /**
- * notification of global removal of applet
- */
- WIDGET_UNPUBLISH_GLOBAL_NOTIFY(SUBJECT_WIDGET_UNPUBLISH_GLOBAL_NOTIFY, 25076L),
-
- /**
- * task reminder
- */
- TASK_REMINDER(SUBJECT_TASK_REMINDER, 25038L),
-
- /**
- * follow record change notifications
- */
- SUBSCRIBED_RECORD_CELL_UPDATED(SUBJECT_SUBSCRIBED_RECORD_CELL_UPDATED, 25336L),
-
- /**
- * follow records are notified by comments
- */
- SUBSCRIBED_RECORD_COMMENTED(SUBJECT_SUBSCRIBED_RECORD_COMMENTED, 25334L),
-
- SUBSCRIBED_DATASHEET_LIMIT(SUBJECT_SUBSCRIBED_DATASHEET_LIMIT, 52372L),
-
- SUBSCRIBED_DATASHEET_RECORD_LIMIT(SUBJECT_SUBSCRIBED_DATASHEET_RECORD_LIMIT, 52375L),
-
- SUBSCRIBED_CAPACITY_LIMIT(SUBJECT_SUBSCRIBED_CAPACITY_LIMIT, 52378L),
-
- SUBSCRIBED_SEATS_LIMIT(SUBJECT_SUBSCRIBED_SEATS_LIMIT, 52379L),
-
- SUBSCRIBED_RECORD_LIMIT(SUBJECT_SUBSCRIBED_RECORD_LIMIT, 52382L),
-
- SUBSCRIBED_API_LIMIT(SUBJECT_SUBSCRIBED_API_LIMIT, 52383L),
-
- SUBSCRIBED_CALENDAR_LIMIT(SUBJECT_SUBSCRIBED_CALENDAR_LIMIT, 52386L),
-
- SUBSCRIBED_FORM_LIMIT(SUBJECT_SUBSCRIBED_FORM_LIMIT, 52387L),
-
- SUBSCRIBED_MIRROR_LIMIT(SUBJECT_SUBSCRIBED_MIRROR_LIMIT, 52390L),
-
- SUBSCRIBED_GANNT_LIMIT(SUBJECT_SUBSCRIBED_GANNT_LIMIT, 52391L),
-
- SUBSCRIBED_FIELD_PERMISSION_LIMIT(SUBJECT_SUBSCRIBED_FIELD_PERMISSION_LIMIT, 52394L),
-
- SUBSCRIBED_FILE_PERMISSION_LIMIT(SUBJECT_SUBSCRIBED_FILE_PERMISSION_LIMIT, 52395L),
-
- SUBSCRIBED_ADMIN_LIMIT(SUBJECT_SUBSCRIBED_ADMIN_LIMIT, 52398L);
-
- private final String subject;
-
- private final Long templateId;
-
- public static Long getTemplateIdBySubject(String subject) {
- Long templateId = null;
- for (ChineseMailTemplate ele : ChineseMailTemplate.values()) {
- if (subject.equals(ele.getSubject())) {
- templateId = ele.getTemplateId();
- break;
- }
- }
- return templateId;
- }
-
- }
-
-
- @AllArgsConstructor
- @Getter
- public enum USMailTemplate {
-
- /**
- * email verification code
- */
- VERIFY_CODE(SUBJECT_VERIFY_CODE, 23612L),
-
- /**
- * primary admin transfer notification
- */
- CHANGE_ADMIN(SUBJECT_CHANGE_ADMIN, 26508L),
-
- /**
- * The payment is successful (there is no English version template. 23462 is a Chinese template)
- */
- PAI_SUCCESS(SUBJECT_PAI_SUCCESS, 23462L),
-
- /**
- * registration verification code
- */
- REGISTER(SUBJECT_REGISTER, 23612L),
-
- /**
- * space invitation notice
- */
- INVITE_NOTIFY(SUBJECT_INVITE_NOTIFY, 26498L),
-
- /**
- * Notice that the space capacity has reached the upper limit
- */
- CAPACITY_FULL(SUBJECT_CAPACITY_FULL, 23616L),
-
- /**
- * record comment mentions
- */
- RECORD_COMMENT(SUBJECT_RECORD_COMMENT, 23617L),
-
- /**
- * member field notification
- */
- DATASHEET_REMIND(SUBJECT_DATASHEET_REMIND, 23618L),
-
- /**
- * transfer of mini program publishing rights
- */
- TRANSFER_WIDGET_NOTIFY(SUBJECT_WIDGET_TRANSFER_NOTIFY, 23619L),
-
- /**
- * small program takedown notice
- */
- UNPUBLISH_WIDGET_NOTIFY(SUBJECT_WIDGET_UNPUBLISH_NOTIFY, 23620L),
-
- /**
- * space station join application
- */
- SPACE_APPLY(SUBJECT_SPACE_APPLY, 26510L),
-
- /**
- * move out of space station notification
- */
- REMOVE_MEMBER(SUBJECT_REMOVE_MEMBER, 23622L),
-
- /**
- * adding records is about to exceed the limit
- */
- ADD_RECORD_SOON_LIMITED(SUBJECT_ADD_RECORD_SOON_LIMITED, 23957L),
-
- /**
- * add record overrun
- */
- ADD_RECORD_LIMITED(SUBJECT_ADD_RECORD_LIMITED, 24008L),
-
- /**
- * the applet was successfully launched
- */
- WIDGET_SUBMIT_SUCCESS(SUBJECT_WIDGET_SUBMIT_SUCCESS, 25083L),
-
- /**
- * failed to launch the applet
- */
- WIDGET_SUBMIT_FAIL(SUBJECT_WIDGET_SUBMIT_FAIL, 25084L),
-
- /**
- * notification of global removal of applet
- */
- WIDGET_UNPUBLISH_GLOBAL_NOTIFY(SUBJECT_WIDGET_UNPUBLISH_GLOBAL_NOTIFY, 25082L),
-
- /**
- * task reminder
- */
- TASK_REMINDER(SUBJECT_TASK_REMINDER, 25039L),
-
- /**
- * follow record change notifications
- */
- SUBSCRIBED_RECORD_CELL_UPDATED(SUBJECT_SUBSCRIBED_RECORD_CELL_UPDATED, 25337L),
-
- /**
- * follow records are notified by comments
- */
- SUBSCRIBED_RECORD_COMMENTED(SUBJECT_SUBSCRIBED_RECORD_COMMENTED, 25335L),
-
- SUBSCRIBED_DATASHEET_LIMIT(SUBJECT_SUBSCRIBED_DATASHEET_LIMIT, 52373L),
-
- SUBSCRIBED_DATASHEET_RECORD_LIMIT(SUBJECT_SUBSCRIBED_DATASHEET_RECORD_LIMIT, 52376L),
-
- SUBSCRIBED_CAPACITY_LIMIT(SUBJECT_SUBSCRIBED_CAPACITY_LIMIT, 52377L),
-
- SUBSCRIBED_SEATS_LIMIT(SUBJECT_SUBSCRIBED_SEATS_LIMIT, 52380L),
-
- SUBSCRIBED_RECORD_LIMIT(SUBJECT_SUBSCRIBED_RECORD_LIMIT, 52381L),
-
- SUBSCRIBED_API_LIMIT(SUBJECT_SUBSCRIBED_API_LIMIT, 52384L),
-
- SUBSCRIBED_CALENDAR_LIMIT(SUBJECT_SUBSCRIBED_CALENDAR_LIMIT, 52385L),
-
- SUBSCRIBED_FORM_LIMIT(SUBJECT_SUBSCRIBED_FORM_LIMIT, 52388L),
-
- SUBSCRIBED_MIRROR_LIMIT(SUBJECT_SUBSCRIBED_MIRROR_LIMIT, 52389L),
-
- SUBSCRIBED_GANNT_LIMIT(SUBJECT_SUBSCRIBED_GANNT_LIMIT, 52392L),
-
- SUBSCRIBED_FIELD_PERMISSION_LIMIT(SUBJECT_SUBSCRIBED_FIELD_PERMISSION_LIMIT, 52393L),
-
- SUBSCRIBED_FILE_PERMISSION_LIMIT(SUBJECT_SUBSCRIBED_FILE_PERMISSION_LIMIT, 52396L),
-
- SUBSCRIBED_ADMIN_LIMIT(SUBJECT_SUBSCRIBED_ADMIN_LIMIT, 52397L);
-
- private final String subject;
-
- private final Long templateId;
-
- public static Long getTemplateIdBySubject(String subject) {
- Long templateId = null;
- for (USMailTemplate ele : USMailTemplate.values()) {
- if (subject.equals(ele.getSubject())) {
- templateId = ele.getTemplateId();
- break;
- }
- }
- return templateId;
- }
-
- }
-
-}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/clock/spring/ClockManager.java b/backend-server/application/src/main/java/com/apitable/shared/clock/spring/ClockManager.java
index 24746cc6b2c15753aa6179a908e3e492f4f64b02..7a4ddb9c001714c973466352c457c33e709f86c0 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/clock/spring/ClockManager.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/clock/spring/ClockManager.java
@@ -18,22 +18,19 @@
package com.apitable.shared.clock.spring;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.OffsetDateTime;
-
-import lombok.extern.slf4j.Slf4j;
-
import com.apitable.core.util.SpringContextHolder;
import com.apitable.shared.clock.Clock;
import com.apitable.shared.clock.DefaultClock;
import com.apitable.shared.clock.MockClock;
import com.apitable.shared.component.SystemEnvironmentVariable;
-
+import com.apitable.shared.config.ServerConfig;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
-import static com.apitable.shared.constants.TimeZoneConstants.DEFAULT_TIME_ZONE;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
@Component
@Slf4j
@@ -41,9 +38,12 @@ public class ClockManager implements InitializingBean {
private Clock clock;
+ private final ServerConfig serverConfig;
+
private final SystemEnvironmentVariable environmentVariable;
- public ClockManager(SystemEnvironmentVariable environmentVariable) {
+ public ClockManager(ServerConfig serverConfig, SystemEnvironmentVariable environmentVariable) {
+ this.serverConfig = serverConfig;
this.environmentVariable = environmentVariable;
}
@@ -72,21 +72,20 @@ public class ClockManager implements InitializingBean {
public LocalDate getLocalDateNow() {
OffsetDateTime utcNow = getUTCNow();
log.info("utc now: {}", utcNow);
- return utcNow.withOffsetSameInstant(DEFAULT_TIME_ZONE).toLocalDate();
+ return utcNow.withOffsetSameInstant(serverConfig.getTimeZone()).toLocalDate();
}
public LocalDateTime getLocalDateTimeNow() {
OffsetDateTime utcNow = getUTCNow();
log.info("utc now: {}", utcNow);
- return utcNow.withOffsetSameInstant(DEFAULT_TIME_ZONE).toLocalDateTime();
+ return utcNow.withOffsetSameInstant(serverConfig.getTimeZone()).toLocalDateTime();
}
@Override
- public void afterPropertiesSet() throws Exception {
+ public void afterPropertiesSet() {
if (environmentVariable.isTestEnabled()) {
clock = new MockClock();
- }
- else {
+ } else {
clock = new DefaultClock();
}
}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java
index 0d3df3be89f618a08985b91c6d62e6bb913f825b..e3ffa00d4bf1e45b5f8051e21776e8cc71c702d8 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java
@@ -264,7 +264,7 @@ public class NotificationFactory implements INotificationFactory {
.builder()
.playerType(a.getIsMemberDeleted() ? PlayerType.MEMBER_DELETED.getType() : PlayerType.MEMBER.getType())
.userName(a.getUserName()).uuid(a.getUuid()).avatar(a.getAvatar()).email(a.getEmail())
- .memberId(a.getMemberId()).memberName(a.getMemberName()).team(a.getTeam())
+ .memberId(a.getMemberId()).memberName(a.getMemberName()).team(a.getTeam()).avatarColor(a.getColor()).nickName(a.getNickName())
.isNickNameModified(a.getIsNickNameModified())
.isMemberNameModified(a.getIsMemberNameModified())
.isDeleted(a.getIsMemberDeleted()).build(), (k1, k2) -> k1)));
diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java
index c361c4ed210fe59a46119c620b9685e1f0f502bf..40a92d58dba33328d5ff41120fb978c3b8d9cb4f 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java
@@ -106,11 +106,7 @@ public class NotificationManager {
public void spaceNotify(NotificationTemplateId templateId, Long userId, String spaceId, Object result) {
HttpServletRequest request = HttpContextUtil.getRequest();
- ContentCachingRequestWrapper requestWrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
- if (requestWrapper == null) {
- log.error("Request Wrapper is null");
- return;
- }
+ ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
Object nodeId = NotificationHelper.resolveNodeId(requestWrapper, result);
if (ObjectUtil.isNotNull(nodeId)) {
String nodeIdStr = nodeId.toString();
diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotifyMailFactory.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotifyMailFactory.java
index ad52ea21e7de6d48b3735afcc996216e51952717..bf83a57c5459f9873dfaa8e2ea1d5bb78ffa2c03 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotifyMailFactory.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotifyMailFactory.java
@@ -37,20 +37,19 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-import lombok.Data;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
+import com.apitable.core.exception.BusinessException;
+import com.apitable.core.util.SpringContextHolder;
+import com.apitable.interfaces.notification.facade.MailFacade;
+import com.apitable.shared.config.properties.EmailSendProperties;
import com.apitable.starter.beetl.autoconfigure.BeetlTemplate;
import com.apitable.starter.mail.autoconfigure.EmailMessage;
import com.apitable.starter.mail.autoconfigure.MailTemplate;
import com.apitable.starter.mail.core.CloudEmailMessage;
import com.apitable.starter.mail.core.CloudMailSender;
-import com.apitable.shared.captcha.email.TencentMailTemplate;
-import com.apitable.shared.config.properties.EmailSendProperties;
-import com.apitable.core.exception.BusinessException;
-import com.apitable.core.util.SpringContextHolder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
@@ -95,9 +94,7 @@ import static com.apitable.shared.constants.MailPropConstants.SUBJECT_WIDGET_UNP
import static java.util.stream.Collectors.toList;
/**
- *
- * Notification Mail Factory
- *
+ * Notification Mail Factory.
*
* @author Shawn Deng
*/
@@ -105,362 +102,468 @@ import static java.util.stream.Collectors.toList;
@Component
public class NotifyMailFactory {
- @Resource
- private BeetlTemplate beetlTemplate;
-
- @Resource
- private EmailSendProperties emailSendProperties;
-
- @Autowired(required = false)
- private CloudMailSender cloudMailSender;
-
- @Autowired(required = false)
- private MailTemplate mailTemplate;
-
- public static NotifyMailFactory me() {
- return SpringContextHolder.getBean(NotifyMailFactory.class);
+ /** */
+ @Resource private BeetlTemplate beetlTemplate;
+
+ /** */
+ @Resource private EmailSendProperties emailSendProperties;
+
+ /** */
+ @Resource private MailFacade mailFacade;
+
+ /** */
+ @Autowired(required = false)
+ private CloudMailSender cloudMailSender;
+
+ /** */
+ @Autowired(required = false)
+ private MailTemplate mailTemplate;
+
+ /**
+ * @return NotifyMailFactory
+ */
+ public static NotifyMailFactory me() {
+ return SpringContextHolder.getBean(NotifyMailFactory.class);
+ }
+
+ /**
+ * @param subjectType subjectType
+ * @param subjectDict subjectDict
+ * @param dict dict
+ * @param tos tos
+ */
+ public void sendMail(
+ final String subjectType,
+ final Dict subjectDict,
+ final Dict dict,
+ final List tos) {
+ if (ObjectUtil.isNotNull(tos)) {
+ Map> tosGroupByLang =
+ tos.stream()
+ .peek(
+ to -> {
+ if (ObjectUtil.isNull(to.getLocale())) {
+ to.setLocale(StrUtil.EMPTY);
+ }
+ })
+ .collect(Collectors.groupingBy(MailWithLang::getLocale));
+ tosGroupByLang.forEach(
+ (lang, mailWithLanguages) -> {
+ final List emails =
+ mailWithLanguages.stream()
+ .map(MailWithLang::getTo).collect(Collectors.toList());
+ sendMail(lang, subjectType, subjectDict, dict, emails);
+ });
}
-
- public void sendMail(String subjectType, Dict subjectDict, Dict dict, List tos) {
- if (ObjectUtil.isNotNull(tos)) {
- Map> tosGroupByLang = tos.stream()
- .peek(to -> {
- if (ObjectUtil.isNull(to.getLocale())) {
- to.setLocale(StrUtil.EMPTY);
- }
- })
- .collect(Collectors.groupingBy(MailWithLang::getLocale));
- tosGroupByLang.forEach((lang, mailWithLanguages) -> {
- final List emails = mailWithLanguages.stream()
- .map(MailWithLang::getTo)
- .collect(Collectors.toList());
- sendMail(lang, subjectType, subjectDict, dict, emails);
- });
- }
+ }
+
+ /**
+ * @param lang lang
+ * @param subjectType subjectType
+ * @param dict dict
+ * @param to to
+ */
+ public void sendMail(
+ final String lang,
+ final String subjectType,
+ final Dict dict,
+ final List to
+ ) {
+ this.sendMail(lang, subjectType, null, dict, to);
+ }
+
+ /**
+ * @param language language
+ * @param subjectType subjectType
+ * @param subjectDict subjectDict
+ * @param dict dict
+ * @param to to
+ */
+ public void sendMail(
+ final String language,
+ final String subjectType,
+ final Dict subjectDict,
+ final Dict dict,
+ final List to) {
+ MailText mailText = new MailText(subjectType, subjectDict).getTemplate();
+
+ String htmlTemplateName = mailText.getHtmlTemplateName();
+ String textTemplateName = mailText.getTextTemplateName();
+ String lang =
+ StrUtil.isNotBlank(language) ? language : Locale.US.toLanguageTag();
+ // load subject.properties
+ Properties properties = loadSubjectProperties(lang);
+ String subject =
+ StrUtil.format(properties.getProperty(subjectType), subjectDict);
+
+ if (StrUtil.hasBlank(htmlTemplateName, textTemplateName, subject)) {
+ log.warn("Lost parameters,"
+ + "please check param(htmlBtl, textBtl, subject).");
+ return;
}
-
- public void sendMail(String lang, String subjectType, Dict dict, List to) {
- this.sendMail(lang, subjectType, null, dict, to);
+ if (cloudMailSender != null) {
+ cloudMailSend(subject, lang, subjectType, dict, to);
+ return;
}
-
- public void sendMail(String lang, String subjectType, Dict subjectDict, Dict dict, List to) {
- MailText mailText = new MailText(subjectType, subjectDict).getTemplate();
-
- String htmlTemplateName = mailText.getHtmlTemplateName();
- String textTemplateName = mailText.getTextTemplateName();
- if (StrUtil.isBlank(lang)) {
- lang = Locale.US.toLanguageTag();
- }
- // load subject.properties
- Properties properties = loadSubjectProperties(lang);
- String subject = StrUtil.format(properties.getProperty(subjectType), subjectDict);
-
- if (StrUtil.hasBlank(htmlTemplateName, textTemplateName, subject)) {
- log.warn("Lost parameters,please check param(htmlBtl, textBtl, subject).");
- return;
- }
- if (cloudMailSender != null) {
- cloudMailSend(subject, lang, subjectType, dict, to);
- return;
- }
- if (mailTemplate == null) {
- log.warn("Mail service not configured");
- return;
- }
- String htmlTemplatePath = loadTemplateResourcePath(lang, htmlTemplateName);
- String textTemplatePath = loadTemplateResourcePath(lang, textTemplateName);
- primevalMailSend(subject, beetlTemplate.render(htmlTemplatePath, dict), beetlTemplate.render(textTemplatePath, dict), to);
+ if (mailTemplate == null) {
+ log.warn("Mail service not configured");
+ return;
}
-
- private Properties loadSubjectProperties(String locale) {
- final Properties properties = new Properties();
- String path = StrUtil.format("templates/notification/enterprise/{}/subject.properties", locale);
- ClassPathResource resource = new ClassPathResource(path);
- if (resource.exists()) {
- try (InputStream in = resource.getInputStream()) {
- properties.load(in);
- }
- catch (IOException e) {
- log.error("load subject error", e);
- throw new BusinessException("Fail to Send Email");
- }
- }
- else {
- ClassPathResource defaultResource = new ClassPathResource("templates/notification/subject.properties");
- try (InputStream in = defaultResource.getInputStream()) {
- properties.load(in);
- }
- catch (IOException e) {
- log.error("load subject error", e);
- throw new BusinessException("Fail to Send Email");
- }
- }
- return properties;
+ String htmlTemplatePath = loadTemplateResourcePath(lang, htmlTemplateName);
+ String textTemplatePath = loadTemplateResourcePath(lang, textTemplateName);
+ primevalMailSend(
+ subject,
+ beetlTemplate.render(htmlTemplatePath, dict),
+ beetlTemplate.render(textTemplatePath, dict),
+ to);
+ }
+
+ private Properties loadSubjectProperties(final String locale) {
+ final Properties properties = new Properties();
+ String path = StrUtil.format(
+ "templates/notification/enterprise/{}/subject.properties", locale);
+ ClassPathResource resource = new ClassPathResource(path);
+ if (resource.exists()) {
+ try (InputStream in = resource.getInputStream()) {
+ properties.load(in);
+ } catch (IOException e) {
+ log.error("load subject error", e);
+ throw new BusinessException("Fail to Send Email");
+ }
+ } else {
+ ClassPathResource defaultResource =
+ new ClassPathResource("templates/notification/subject.properties");
+ try (InputStream in = defaultResource.getInputStream()) {
+ properties.load(in);
+ } catch (IOException e) {
+ log.error("load subject error", e);
+ throw new BusinessException("Fail to Send Email");
+ }
}
-
- private String loadTemplateResourcePath(String locale, String templateName) {
- String templatePath = StrUtil.format("templates/notification/enterprise/{}/{}", locale, templateName);
- ClassPathResource resource = new ClassPathResource(templatePath);
- if (resource.exists()) {
- // load locale priority
- return StrUtil.format("notification/enterprise/{}/{}", locale, templateName);
- }
- else {
- return StrUtil.format("notification/{}", templateName);
- }
+ return properties;
+ }
+
+ private String loadTemplateResourcePath(
+ final String locale, final String templateName) {
+ String templatePath =
+ StrUtil.format("templates/notification/enterprise/{}/{}",
+ locale, templateName);
+ ClassPathResource resource = new ClassPathResource(templatePath);
+ if (resource.exists()) {
+ // load locale priority
+ return StrUtil.format("notification/enterprise/{}/{}",
+ locale, templateName);
+ } else {
+ return StrUtil.format("notification/{}", templateName);
}
-
- public void notify(String subject, String textBtl) {
- this.notify(emailSendProperties.getPersonal(), subject, null, null, textBtl, Collections.singletonList("devops@apitable.com"));
+ }
+
+ /**
+ * @param subject subject
+ * @param textBtl textBtl
+ */
+ public void notify(final String subject, final String textBtl) {
+ this.notify(
+ emailSendProperties.getPersonal(),
+ subject,
+ null,
+ null,
+ textBtl,
+ Collections.singletonList("devops@apitable.com"));
+ }
+
+ /**
+ * *
+ *
+ * @param personal personal
+ * @param subject subject
+ * @param subjectType subjectType
+ * @param dict dict
+ * @param textBtl textBtl
+ * @param to to
+ */
+ public void notify(
+ final String personal,
+ final String subject,
+ final String subjectType,
+ final Dict dict,
+ final String textBtl,
+ final List to) {
+ if (cloudMailSender != null) {
+ CloudEmailMessage message = new CloudEmailMessage();
+ message.setSubject(subject);
+ message.setPersonal(personal);
+ message.setTo(to);
+ JSONObject obj = JSONUtil.createObj();
+ if (subjectType != null) {
+ message.setTemplateId(
+ mailFacade.getCloudMailTemplateId(null, subjectType));
+ obj.putAll(dict);
+ } else {
+ message.setTemplateId(
+ mailFacade.getCloudMailTemplateId(null, SUBJECT_WARN_NOTIFY));
+ obj.putOpt("content", textBtl);
+ }
+ message.setTemplateData(obj.toString());
+ cloudMailSender.send(message);
+ return;
}
-
- public void notify(String personal, String subject, String subjectType, Dict dict, String textBtl, List to) {
- if (cloudMailSender != null) {
- CloudEmailMessage message = new CloudEmailMessage();
- message.setSubject(subject);
- message.setPersonal(personal);
- message.setTo(to);
- JSONObject obj = JSONUtil.createObj();
- if (subjectType != null) {
- message.setTemplateId(TencentMailTemplate.getTemplateId(null, subjectType));
- obj.putAll(dict);
- }
- else {
- message.setTemplateId(TencentMailTemplate.getTemplateId(null, SUBJECT_WARN_NOTIFY));
- obj.putOpt("content", textBtl);
- }
- message.setTemplateData(obj.toString());
- cloudMailSender.send(message);
- return;
- }
- if (mailTemplate == null) {
- log.info("Mail service not configured");
- return;
- }
- EmailMessage emailMessage = new EmailMessage();
- emailMessage.setPersonal(personal);
- emailMessage.setSubject(subject);
- emailMessage.setTo(to);
- if (subjectType != null) {
- return;
- }
- if (textBtl != null) {
- emailMessage.setPlainText(textBtl);
- }
- mailTemplate.send(emailMessage);
+ if (mailTemplate == null) {
+ log.info("Mail service not configured");
+ return;
}
-
- private void cloudMailSend(String subject, String lang, String subjectType, Dict dict, List to) {
- CloudEmailMessage message = new CloudEmailMessage();
- message.setSubject(subject);
- message.setPersonal(emailSendProperties.getPersonal());
- message.setTo(to);
- message.setTemplateId(TencentMailTemplate.getTemplateId(lang, subjectType));
- JSONObject obj = JSONUtil.createObj();
- obj.putAll(dict);
- message.setTemplateData(obj.toString());
- cloudMailSender.send(message);
+ EmailMessage emailMessage = new EmailMessage();
+ emailMessage.setPersonal(personal);
+ emailMessage.setSubject(subject);
+ emailMessage.setTo(to);
+ if (subjectType != null) {
+ return;
+ }
+ if (textBtl != null) {
+ emailMessage.setPlainText(textBtl);
+ }
+ mailTemplate.send(emailMessage);
+ }
+
+ private void cloudMailSend(
+ final String subject,
+ final String lang,
+ final String subjectType,
+ final Dict dict,
+ final List to) {
+ CloudEmailMessage message = new CloudEmailMessage();
+ message.setSubject(subject);
+ message.setPersonal(emailSendProperties.getPersonal());
+ message.setTo(to);
+ message.setTemplateId(mailFacade.getCloudMailTemplateId(lang, subjectType));
+ JSONObject obj = JSONUtil.createObj();
+ obj.putAll(dict);
+ message.setTemplateData(obj.toString());
+ cloudMailSender.send(message);
+ }
+
+ private void primevalMailSend(
+ final String subject,
+ final String htmlBody,
+ final String plainText,
+ final List to
+ ) {
+ EmailMessage[] messages = new EmailMessage[to.size()];
+ for (int i = 0; i < to.size(); i++) {
+ EmailMessage emailMessage = new EmailMessage();
+ emailMessage.setPersonal(emailSendProperties.getPersonal());
+ emailMessage.setSubject(subject);
+ emailMessage.setTo(Collections.singletonList(to.get(i)));
+ emailMessage.setPlainText(plainText);
+ emailMessage.setHtmlText(htmlBody);
+ messages[i] = emailMessage;
+ }
+ mailTemplate.send(messages);
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class MailWithLang {
+ /** * */
+ private String locale;
+
+ /** * */
+ private String to;
+
+ /**
+ *
+ * @param targetLocale targetLocale
+ * @param email email
+ */
+ public MailWithLang(final String targetLocale, final String email) {
+ this.locale = targetLocale;
+ this.to = email;
}
- private void primevalMailSend(String subject, String htmlBody, String plainText, List to) {
- EmailMessage[] messages = new EmailMessage[to.size()];
- for (int i = 0; i < to.size(); i++) {
- EmailMessage emailMessage = new EmailMessage();
- emailMessage.setPersonal(emailSendProperties.getPersonal());
- emailMessage.setSubject(subject);
- emailMessage.setTo(Collections.singletonList(to.get(i)));
- emailMessage.setPlainText(plainText);
- emailMessage.setHtmlText(htmlBody);
- messages[i] = emailMessage;
- }
- mailTemplate.send(messages);
+ /**
+ * *
+ *
+ * @param data data
+ * @param mapper mapper
+ * @param T
+ * @return List
+ */
+ public static List convert(
+ final List data,
+ final Function super T, ? extends MailWithLang> mapper
+ ) {
+ return Optional.ofNullable(data).orElseGet(ArrayList::new).stream()
+ .map(mapper)
+ .collect(toList());
}
+ }
+
+ static final class MailText {
- @Data
- @NoArgsConstructor
- public static class MailWithLang {
- private String locale;
+ /** * */
+ @Getter private String htmlTemplateName;
- private String to;
+ /** * */
+ @Getter private String textTemplateName;
- public MailWithLang(String locale, String to) {
- this.locale = locale;
- this.to = to;
- }
+ /** * */
+ @Getter private final String subjectType;
- public static List convert(List data, Function super T, ? extends MailWithLang> mapper) {
- return Optional.ofNullable(data).orElseGet(ArrayList::new).stream().map(mapper).collect(toList());
- }
+ /** * */
+ @Getter private final Dict subjectDict;
+ MailText(final String type, final Dict dict) {
+ this.subjectType = type;
+ this.subjectDict = dict;
}
- static final class MailText {
-
- @Getter
- String htmlTemplateName;
-
- @Getter
- String textTemplateName;
-
- @Getter
- String subject;
-
- String subjectType;
-
- Dict subjectDict;
-
- public MailText(String subjectType, Dict subjectDict) {
- this.subjectType = subjectType;
- this.subjectDict = subjectDict;
- }
-
- public MailText getTemplate() {
- // switch email template
- switch (this.subjectType) {
- case SUBJECT_INVITE_NOTIFY:
- this.htmlTemplateName = "invite-email-html.btl";
- this.textTemplateName = "invite-email-text.btl";
- break;
- case SUBJECT_REMOVE_MEMBER:
- this.htmlTemplateName = "remove-member-html.btl";
- this.textTemplateName = "remove-member-text.btl";
- break;
- case SUBJECT_DATASHEET_REMIND:
- this.htmlTemplateName = "remind-member-html.btl";
- this.textTemplateName = "remind-member-text.btl";
- break;
- case SUBJECT_SPACE_APPLY:
- this.htmlTemplateName = "space-apply-html.btl";
- this.textTemplateName = "space-apply-text.btl";
- break;
- case SUBJECT_RECORD_COMMENT:
- this.htmlTemplateName = "remind-comment-html.btl";
- this.textTemplateName = "remind-comment-text.btl";
- break;
- case SUBJECT_WIDGET_UNPUBLISH_NOTIFY:
- this.htmlTemplateName = "widget-unpublish-notify-html.btl";
- this.textTemplateName = "widget-unpublish-notify-text.btl";
- break;
- case SUBJECT_WIDGET_UNPUBLISH_GLOBAL_NOTIFY:
- this.htmlTemplateName = "widget-unpublish-global-notify-html.btl";
- this.textTemplateName = "widget-unpublish-global-notify-text.btl";
- break;
- case SUBJECT_WIDGET_TRANSFER_NOTIFY:
- this.htmlTemplateName = "widget-transfer-notify-html.btl";
- this.textTemplateName = "widget-transfer-notify-text.btl";
- break;
- case SUBJECT_CHANGE_ADMIN:
- this.htmlTemplateName = "admin-notify-html.btl";
- this.textTemplateName = "admin-notify-text.btl";
- break;
- case SUBJECT_VERIFY_CODE:
- this.htmlTemplateName = "verification-code-html.btl";
- this.textTemplateName = "verification-code-text.btl";
- break;
- case SUBJECT_REGISTER:
- this.htmlTemplateName = "register-email-html.btl";
- this.textTemplateName = "register-email-text.btl";
- break;
- case SUBJECT_CAPACITY_FULL:
- this.htmlTemplateName = "capacity-full-html.btl";
- this.textTemplateName = "capacity-full-text.btl";
- break;
- case SUBJECT_PAI_SUCCESS:
- this.htmlTemplateName = "pay-success-html.btl";
- this.textTemplateName = "pay-success-text.btl";
- break;
- case SUBJECT_ADD_RECORD_SOON_LIMITED:
- this.htmlTemplateName = "add-record-reaching-limited-html.btl";
- this.textTemplateName = "add-record-reaching-limited-text.btl";
- break;
- case SUBJECT_ADD_RECORD_LIMITED:
- this.htmlTemplateName = "add-record-reached-limited-html.btl";
- this.textTemplateName = "add-record-reached-limited-text.btl";
- break;
- case SUBJECT_WIDGET_SUBMIT_SUCCESS:
- this.htmlTemplateName = "widget-submit-success-html.btl";
- this.textTemplateName = "widget-submit-success-text.btl";
- break;
- case SUBJECT_WIDGET_SUBMIT_FAIL:
- this.htmlTemplateName = "widget-submit-fail-html.btl";
- this.textTemplateName = "widget-submit-fail-text.btl";
- break;
- case SUBJECT_WIDGET_QUALIFICATION_AUTH_SUCCESS:
- this.htmlTemplateName = "widget-qualification-auth-success-html.btl";
- this.textTemplateName = "widget-qualification-auth-success-text.btl";
- break;
- case SUBJECT_WIDGET_QUALIFICATION_AUTH_FAIL:
- this.htmlTemplateName = "widget-qualification-auth-fail-html.btl";
- this.textTemplateName = "widget-qualification-auth-fail-text.btl";
- break;
- case SUBJECT_TASK_REMINDER:
- htmlTemplateName = "task-reminder-html.btl";
- textTemplateName = "task-reminder-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_RECORD_CELL_UPDATED:
- htmlTemplateName = "subscribed-record-cell-updated-html.btl";
- textTemplateName = "subscribed-record-cell-updated-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_RECORD_COMMENTED:
- htmlTemplateName = "subscribed-record-commented-html.btl";
- textTemplateName = "subscribed-record-commented-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_DATASHEET_LIMIT:
- htmlTemplateName = "subscribed-datasheet-limit-html.btl";
- textTemplateName = "subscribed-datasheet-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_DATASHEET_RECORD_LIMIT:
- htmlTemplateName = "subscribed-datasheet-record-html.btl";
- textTemplateName = "subscribed-datasheet-record-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_CAPACITY_LIMIT:
- htmlTemplateName = "subscribed-capacity-html.btl";
- textTemplateName = "subscribed-capacity-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_SEATS_LIMIT:
- htmlTemplateName = "subscribed-seats-limit-html.btl";
- textTemplateName = "subscribed-seats-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_RECORD_LIMIT:
- htmlTemplateName = "subscribed-record-limit-html.btl";
- textTemplateName = "subscribed-record-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_API_LIMIT:
- htmlTemplateName = "subscribed-api-limit-html.btl";
- textTemplateName = "subscribed-api-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_CALENDAR_LIMIT:
- htmlTemplateName = "subscribed-calendar-limit-html.btl";
- textTemplateName = "subscribed-calendar-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_FORM_LIMIT:
- htmlTemplateName = "subscribed-form-limit-html.btl";
- textTemplateName = "subscribed-form-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_MIRROR_LIMIT:
- htmlTemplateName = "subscribed-mirror-limit-html.btl";
- textTemplateName = "subscribed-mirror-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_GANNT_LIMIT:
- htmlTemplateName = "subscribed-gannt-limit-html.btl";
- textTemplateName = "subscribed-gannt-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_FIELD_PERMISSION_LIMIT:
- htmlTemplateName = "subscribed-field-permission-limit-html.btl";
- textTemplateName = "subscribed-field-permission-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_FILE_PERMISSION_LIMIT:
- htmlTemplateName = "subscribed-file-permission-limit-html.btl";
- textTemplateName = "subscribed-file-permission-limit-text.btl";
- break;
- case SUBJECT_SUBSCRIBED_ADMIN_LIMIT:
- htmlTemplateName = "subscribed-admin-limit-html.btl";
- textTemplateName = "subscribed-admin-limit-text.btl";
- break;
- default:
- break;
- }
- return this;
- }
+ public MailText getTemplate() {
+ // switch email template
+ switch (this.subjectType) {
+ case SUBJECT_INVITE_NOTIFY:
+ this.htmlTemplateName = "invite-email-html.btl";
+ this.textTemplateName = "invite-email-text.btl";
+ break;
+ case SUBJECT_REMOVE_MEMBER:
+ this.htmlTemplateName = "remove-member-html.btl";
+ this.textTemplateName = "remove-member-text.btl";
+ break;
+ case SUBJECT_DATASHEET_REMIND:
+ this.htmlTemplateName = "remind-member-html.btl";
+ this.textTemplateName = "remind-member-text.btl";
+ break;
+ case SUBJECT_SPACE_APPLY:
+ this.htmlTemplateName = "space-apply-html.btl";
+ this.textTemplateName = "space-apply-text.btl";
+ break;
+ case SUBJECT_RECORD_COMMENT:
+ this.htmlTemplateName = "remind-comment-html.btl";
+ this.textTemplateName = "remind-comment-text.btl";
+ break;
+ case SUBJECT_WIDGET_UNPUBLISH_NOTIFY:
+ this.htmlTemplateName = "widget-unpublish-notify-html.btl";
+ this.textTemplateName = "widget-unpublish-notify-text.btl";
+ break;
+ case SUBJECT_WIDGET_UNPUBLISH_GLOBAL_NOTIFY:
+ this.htmlTemplateName = "widget-unpublish-global-notify-html.btl";
+ this.textTemplateName = "widget-unpublish-global-notify-text.btl";
+ break;
+ case SUBJECT_WIDGET_TRANSFER_NOTIFY:
+ this.htmlTemplateName = "widget-transfer-notify-html.btl";
+ this.textTemplateName = "widget-transfer-notify-text.btl";
+ break;
+ case SUBJECT_CHANGE_ADMIN:
+ this.htmlTemplateName = "admin-notify-html.btl";
+ this.textTemplateName = "admin-notify-text.btl";
+ break;
+ case SUBJECT_VERIFY_CODE:
+ this.htmlTemplateName = "verification-code-html.btl";
+ this.textTemplateName = "verification-code-text.btl";
+ break;
+ case SUBJECT_REGISTER:
+ this.htmlTemplateName = "register-email-html.btl";
+ this.textTemplateName = "register-email-text.btl";
+ break;
+ case SUBJECT_CAPACITY_FULL:
+ this.htmlTemplateName = "capacity-full-html.btl";
+ this.textTemplateName = "capacity-full-text.btl";
+ break;
+ case SUBJECT_PAI_SUCCESS:
+ this.htmlTemplateName = "pay-success-html.btl";
+ this.textTemplateName = "pay-success-text.btl";
+ break;
+ case SUBJECT_ADD_RECORD_SOON_LIMITED:
+ this.htmlTemplateName = "add-record-reaching-limited-html.btl";
+ this.textTemplateName = "add-record-reaching-limited-text.btl";
+ break;
+ case SUBJECT_ADD_RECORD_LIMITED:
+ this.htmlTemplateName = "add-record-reached-limited-html.btl";
+ this.textTemplateName = "add-record-reached-limited-text.btl";
+ break;
+ case SUBJECT_WIDGET_SUBMIT_SUCCESS:
+ this.htmlTemplateName = "widget-submit-success-html.btl";
+ this.textTemplateName = "widget-submit-success-text.btl";
+ break;
+ case SUBJECT_WIDGET_SUBMIT_FAIL:
+ this.htmlTemplateName = "widget-submit-fail-html.btl";
+ this.textTemplateName = "widget-submit-fail-text.btl";
+ break;
+ case SUBJECT_WIDGET_QUALIFICATION_AUTH_SUCCESS:
+ this.htmlTemplateName = "widget-qualification-auth-success-html.btl";
+ this.textTemplateName = "widget-qualification-auth-success-text.btl";
+ break;
+ case SUBJECT_WIDGET_QUALIFICATION_AUTH_FAIL:
+ this.htmlTemplateName = "widget-qualification-auth-fail-html.btl";
+ this.textTemplateName = "widget-qualification-auth-fail-text.btl";
+ break;
+ case SUBJECT_TASK_REMINDER:
+ htmlTemplateName = "task-reminder-html.btl";
+ textTemplateName = "task-reminder-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_RECORD_CELL_UPDATED:
+ htmlTemplateName = "subscribed-record-cell-updated-html.btl";
+ textTemplateName = "subscribed-record-cell-updated-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_RECORD_COMMENTED:
+ htmlTemplateName = "subscribed-record-commented-html.btl";
+ textTemplateName = "subscribed-record-commented-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_DATASHEET_LIMIT:
+ htmlTemplateName = "subscribed-datasheet-limit-html.btl";
+ textTemplateName = "subscribed-datasheet-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_DATASHEET_RECORD_LIMIT:
+ htmlTemplateName = "subscribed-datasheet-record-html.btl";
+ textTemplateName = "subscribed-datasheet-record-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_CAPACITY_LIMIT:
+ htmlTemplateName = "subscribed-capacity-html.btl";
+ textTemplateName = "subscribed-capacity-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_SEATS_LIMIT:
+ htmlTemplateName = "subscribed-seats-limit-html.btl";
+ textTemplateName = "subscribed-seats-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_RECORD_LIMIT:
+ htmlTemplateName = "subscribed-record-limit-html.btl";
+ textTemplateName = "subscribed-record-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_API_LIMIT:
+ htmlTemplateName = "subscribed-api-limit-html.btl";
+ textTemplateName = "subscribed-api-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_CALENDAR_LIMIT:
+ htmlTemplateName = "subscribed-calendar-limit-html.btl";
+ textTemplateName = "subscribed-calendar-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_FORM_LIMIT:
+ htmlTemplateName = "subscribed-form-limit-html.btl";
+ textTemplateName = "subscribed-form-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_MIRROR_LIMIT:
+ htmlTemplateName = "subscribed-mirror-limit-html.btl";
+ textTemplateName = "subscribed-mirror-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_GANNT_LIMIT:
+ htmlTemplateName = "subscribed-gannt-limit-html.btl";
+ textTemplateName = "subscribed-gannt-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_FIELD_PERMISSION_LIMIT:
+ htmlTemplateName = "subscribed-field-permission-limit-html.btl";
+ textTemplateName = "subscribed-field-permission-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_FILE_PERMISSION_LIMIT:
+ htmlTemplateName = "subscribed-file-permission-limit-html.btl";
+ textTemplateName = "subscribed-file-permission-limit-text.btl";
+ break;
+ case SUBJECT_SUBSCRIBED_ADMIN_LIMIT:
+ htmlTemplateName = "subscribed-admin-limit-html.btl";
+ textTemplateName = "subscribed-admin-limit-text.btl";
+ break;
+ default:
+ break;
+ }
+ return this;
}
+ }
}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java
index ab9e640ac68bc4b0a3930e69fb2d8a84d64b0c4c..527b106e05bd8fa865df3ae91e03805bc88331d2 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java
@@ -18,33 +18,29 @@
package com.apitable.shared.component.notification.observer;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import javax.annotation.Resource;
-
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-
-import com.apitable.shared.component.notification.NotificationHelper;
-import com.apitable.player.ro.NotificationCreateRo;
import com.apitable.organization.service.IMemberService;
+import com.apitable.player.ro.NotificationCreateRo;
+import com.apitable.shared.component.notification.NotificationHelper;
+import com.apitable.shared.sysconfig.i18n.I18nStringsUtil;
import com.apitable.space.service.ISpaceService;
import com.apitable.workspace.service.INodeService;
-import com.apitable.shared.sysconfig.i18n.I18nStringsUtil;
+
+import javax.annotation.Resource;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_MINUTE_PATTERN;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_MEMBER_NAME;
-import static com.apitable.shared.constants.NotificationConstants.EMAIL_RECORD_ID;
-import static com.apitable.shared.constants.NotificationConstants.INVOLVE_RECORD_IDS;
+import static com.apitable.shared.constants.NotificationConstants.*;
/**
*
diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/package-info.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef7bebba0e21b7f5567348b7d2db46970ddf1caf
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * APITable
+ * Copyright (C) 2022 APITable Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ *
+ * @author Chambers
+ */
+package com.apitable.shared.component.notification;
diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/scanner/ApiResourceScanner.java b/backend-server/application/src/main/java/com/apitable/shared/component/scanner/ApiResourceScanner.java
index 99541db9397552d42555a2c6b868dd84f69ebdd2..d065b40d9d816df42e19680603fc9d00285824da 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/component/scanner/ApiResourceScanner.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/component/scanner/ApiResourceScanner.java
@@ -25,16 +25,18 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.Resource;
+
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.StrUtil;
-import lombok.extern.slf4j.Slf4j;
-
+import com.apitable.shared.component.ResourceDefinition;
+import com.apitable.shared.component.SystemEnvironmentVariable;
import com.apitable.shared.component.scanner.annotation.ApiResource;
import com.apitable.shared.component.scanner.annotation.GetResource;
import com.apitable.shared.component.scanner.annotation.PostResource;
-import com.apitable.shared.component.ResourceDefinition;
-import com.apitable.shared.util.IgnorePathHelper;
import com.apitable.shared.util.AopTargetUtils;
+import com.apitable.shared.util.IgnorePathHelper;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -47,228 +49,278 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
- *
- * api source scanner
- *
+ * api source scanner.
*
* @author Shawn Deng
*/
@Slf4j
@Component
-public class ApiResourceScanner implements BeanPostProcessor, Ordered, ApplicationContextAware {
-
- /**
- * string connector
- */
- private static final String LINK_SYMBOL = "$";
-
- private ApplicationContext applicationContext;
-
- private ApiResourceFactory apiResourceFactory;
-
- public ApiResourceFactory getApiResourceFactory() {
- if (apiResourceFactory == null) {
- apiResourceFactory = applicationContext.getBean(ApiResourceFactory.class);
- }
- return apiResourceFactory;
- }
-
- @Override
- public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
- return bean;
- }
-
- @Override
- public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
- Object aopTarget = AopTargetUtils.getTarget(bean);
+public class ApiResourceScanner
+ implements BeanPostProcessor, Ordered, ApplicationContextAware {
- if (aopTarget == null) {
- aopTarget = bean;
- }
+ /** string connector. */
+ private static final String LINK_SYMBOL = "$";
- final Class> clazz = aopTarget.getClass();
+ /** minuend. */
+ private static final int MINUEND = 11;
- final boolean controllerFlag = checkControllerFlag(clazz);
- if (!controllerFlag) {
- return bean;
- }
+ /** */
+ private ApplicationContext applicationContext;
- final List apiResourceDefinitions = doScan(clazz);
+ /** */
+ private ApiResourceFactory apiResourceFactory;
- persistApiResources(apiResourceDefinitions);
+ /** */
+ @Resource private SystemEnvironmentVariable systemEnvironmentVariable;
- return bean;
+ /**
+ * GetApiResourceFactory.
+ *
+ * @return ApiResourceFactory
+ */
+ public ApiResourceFactory getApiResourceFactory() {
+ if (apiResourceFactory == null) {
+ apiResourceFactory =
+ applicationContext.getBean(ApiResourceFactory.class);
}
-
- @Override
- public int getOrder() {
- return Ordered.LOWEST_PRECEDENCE - 11;
+ return apiResourceFactory;
+ }
+
+ /** * */
+ @Override
+ public Object postProcessBeforeInitialization(
+ final Object bean, final String beanName
+ ) throws BeansException {
+ return bean;
+ }
+
+ /** * */
+ @Override
+ public Object postProcessAfterInitialization(
+ final Object bean, final String beanName
+ ) throws BeansException {
+ if (systemEnvironmentVariable.isTestEnabled()) {
+ return bean;
}
+ Object aopTarget = AopTargetUtils.getTarget(bean);
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = applicationContext;
+ if (aopTarget == null) {
+ aopTarget = bean;
}
- /**
- * whether class is controller
- * @param clazz class
- * @return true | false
- */
- private boolean checkControllerFlag(final Class> clazz) {
- final Annotation[] annotations = clazz.getAnnotations();
-
- for (final Annotation annotation : annotations) {
- if (RestController.class.equals(annotation.annotationType())
- || Controller.class.equals(annotation.annotationType())) {
- return true;
- }
- }
- return false;
- }
+ final Class> clazz = aopTarget.getClass();
- /**
- * save api resource
- * @param apiResources api resource list
- */
- private void persistApiResources(final List apiResources) {
- getApiResourceFactory().registerDefinition(apiResources);
+ final boolean controllerFlag = checkControllerFlag(clazz);
+ if (!controllerFlag) {
+ return bean;
}
- /**
- * scan bean
- * @param clazz class
- * @return resource list
- */
- private List doScan(final Class> clazz) {
- final ArrayList apiResources = new ArrayList<>();
- final ApiResource classApiAnnotation = clazz.getAnnotation(ApiResource.class);
- if (classApiAnnotation != null && !classApiAnnotation.ignore()) {
- final Method[] declaredMethods = clazz.getDeclaredMethods();
- if (declaredMethods.length > 0) {
- for (final Method declaredMethod : declaredMethods) {
- final Annotation annotation = this.getOnMethod(declaredMethod);
- if (annotation != null) {
- final ResourceDefinition definition = createDefinition(clazz, declaredMethod, annotation);
- apiResources.add(definition);
- }
- }
- }
- }
-
- return apiResources;
+ final List apiResourceDefinitions = doScan(clazz);
+
+ persistApiResources(apiResourceDefinitions);
+
+ return bean;
+ }
+
+ /**
+ * *
+ *
+ * @return order
+ */
+ @Override
+ public int getOrder() {
+ return Ordered.LOWEST_PRECEDENCE - MINUEND;
+ }
+
+ /**
+ * *
+ *
+ * @param context applicationContext
+ */
+ @Override
+ public void setApplicationContext(final ApplicationContext context)
+ throws BeansException {
+ this.applicationContext = context;
+ }
+
+ /**
+ * whether class is controller.
+ *
+ * @param clazz class
+ * @return true | false
+ */
+ private boolean checkControllerFlag(final Class> clazz) {
+ final Annotation[] annotations = clazz.getAnnotations();
+
+ for (final Annotation annotation : annotations) {
+ if (RestController.class.equals(annotation.annotationType())
+ || Controller.class.equals(annotation.annotationType())) {
+ return true;
+ }
}
-
- private ResourceDefinition createDefinition(final Class> clazz, final Method method,
- final Annotation apiResource) {
- final ResourceDefinition resourceDefinition = new ResourceDefinition();
- resourceDefinition.setClassName(clazz.getSimpleName());
- resourceDefinition.setMethodName(method.getName());
-
- String modularCode;
- final ApiResource classApiAnnotation = clazz.getAnnotation(ApiResource.class);
- if (StrUtil.isEmpty(classApiAnnotation.code())) {
- final String className = clazz.getSimpleName();
- modularCode = getControllerClassPrefix(className);
- }
- else {
- modularCode = classApiAnnotation.code();
- }
- resourceDefinition.setModularCode(modularCode);
- resourceDefinition.setModularName(classApiAnnotation.name());
-
- final String resourceCode = invokeAnnotationMethod(apiResource, "code");
- if (StrUtil.isEmpty(resourceCode)) {
- final String definitionCode = StrUtil.join(LINK_SYMBOL, StrUtil.toUnderlineCase(modularCode),
- StrUtil.toUnderlineCase(method.getName()));
- resourceDefinition.setResourceCode(definitionCode);
- }
- else {
- resourceDefinition.setResourceCode(StrUtil.join(LINK_SYMBOL, modularCode, resourceCode));
- }
-
- final String name = invokeAnnotationMethod(apiResource, "name");
- resourceDefinition.setResourceName(name);
- final String[] path = invokeAnnotationMethod(apiResource, "path");
- resourceDefinition.setResourceUrl(getControllerClassRequestPath(clazz) + path[0]);
- final Boolean requiredLogin = invokeAnnotationMethod(apiResource, "requiredLogin");
- resourceDefinition.setRequiredLogin(requiredLogin);
- if (!requiredLogin) {
- IgnorePathHelper.getInstant().add(resourceDefinition.getResourceUrl());
+ return false;
+ }
+
+ /**
+ * save api resource.
+ *
+ * @param apiResources api resource list
+ */
+ private void persistApiResources(
+ final List apiResources) {
+ getApiResourceFactory().registerDefinition(apiResources);
+ }
+
+ /**
+ * scan bean.
+ *
+ * @param clazz class
+ * @return resource list
+ */
+ private List doScan(final Class> clazz) {
+ final ArrayList apiResources = new ArrayList<>();
+ final ApiResource classApiAnnotation =
+ clazz.getAnnotation(ApiResource.class);
+ if (classApiAnnotation != null && !classApiAnnotation.ignore()) {
+ final Method[] declaredMethods = clazz.getDeclaredMethods();
+ if (declaredMethods.length > 0) {
+ for (final Method declaredMethod : declaredMethods) {
+ final Annotation annotation = this.getOnMethod(declaredMethod);
+ if (annotation != null) {
+ final ResourceDefinition definition =
+ createDefinition(clazz, declaredMethod, annotation);
+ apiResources.add(definition);
+ }
}
- final Boolean requiredPermission = invokeAnnotationMethod(apiResource, "requiredPermission");
- resourceDefinition.setRequiredPermission(requiredPermission);
- final String[] tags = invokeAnnotationMethod(apiResource, "tags");
- resourceDefinition.setTags(tags);
- final Boolean requiredAccessDomain = invokeAnnotationMethod(apiResource, "requiredAccessDomain");
- resourceDefinition.setRequiredAccessDomain(requiredAccessDomain);
-
- final RequestMethod[] requestMethods = invokeAnnotationMethod(apiResource, "method");
- final List methodNames = new ArrayList<>();
- for (final RequestMethod requestMethod : requestMethods) {
- methodNames.add(requestMethod.name());
- }
- resourceDefinition.setHttpMethod(StrUtil.join(",", methodNames));
-
- final String localMacAddress = NetUtil.getLocalhostStr();
- resourceDefinition.setIpAddress(localMacAddress == null ? "" : localMacAddress);
- resourceDefinition.setCreateTime(LocalDateTime.now());
- return resourceDefinition;
+ }
}
- @SuppressWarnings("unchecked")
- private T invokeAnnotationMethod(final Annotation apiResource, final String methodName) {
- try {
- final Class extends Annotation> annotationType = apiResource.annotationType();
- final Method method = annotationType.getMethod(methodName);
- return (T) method.invoke(apiResource);
- }
- catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
- log.error("fail to scan api resources!", e);
- throw new RuntimeException("fail to scan api resources!", e);
- }
+ return apiResources;
+ }
+
+ private ResourceDefinition createDefinition(
+ final Class> clazz, final Method method, final Annotation apiResource
+ ) {
+ final ResourceDefinition resourceDefinition = new ResourceDefinition();
+ resourceDefinition.setClassName(clazz.getSimpleName());
+ resourceDefinition.setMethodName(method.getName());
+
+ String modularCode;
+ final ApiResource classApiAnnotation =
+ clazz.getAnnotation(ApiResource.class);
+ if (StrUtil.isEmpty(classApiAnnotation.code())) {
+ final String className = clazz.getSimpleName();
+ modularCode = getControllerClassPrefix(className);
+ } else {
+ modularCode = classApiAnnotation.code();
}
-
- private String getControllerClassRequestPath(final Class> clazz) {
- String result = "";
-
- final ApiResource controllerRequestMapping = clazz.getDeclaredAnnotation(ApiResource.class);
- if (controllerRequestMapping != null) {
- final String[] paths = controllerRequestMapping.path();
- if (paths.length > 0) {
- result = paths[0];
- }
- else {
- result = "";
- }
- }
-
- return result;
+ resourceDefinition.setModularCode(modularCode);
+ resourceDefinition.setModularName(classApiAnnotation.name());
+
+ final String resourceCode = invokeAnnotationMethod(apiResource, "code");
+ if (StrUtil.isEmpty(resourceCode)) {
+ final String definitionCode =
+ StrUtil.join(
+ LINK_SYMBOL,
+ StrUtil.toUnderlineCase(modularCode),
+ StrUtil.toUnderlineCase(method.getName()));
+ resourceDefinition.setResourceCode(definitionCode);
+ } else {
+ resourceDefinition.setResourceCode(
+ StrUtil.join(LINK_SYMBOL, modularCode, resourceCode));
}
- private String getControllerClassPrefix(final String className) {
- final int controllerIndex = className.indexOf("Controller");
- if (controllerIndex == -1) {
- throw new IllegalArgumentException("Controller naming error, should ends with Controller!");
- }
- return className.substring(0, controllerIndex);
+ final String name = invokeAnnotationMethod(apiResource, "name");
+ resourceDefinition.setResourceName(name);
+ final String[] path = invokeAnnotationMethod(apiResource, "path");
+ resourceDefinition.setResourceUrl(
+ getControllerClassRequestPath(clazz) + path[0]);
+ final Boolean requiredLogin =
+ invokeAnnotationMethod(apiResource, "requiredLogin");
+ resourceDefinition.setRequiredLogin(requiredLogin);
+ if (!requiredLogin) {
+ IgnorePathHelper.getInstant().add(resourceDefinition.getResourceUrl());
+ }
+ final Boolean requiredPermission =
+ invokeAnnotationMethod(apiResource, "requiredPermission");
+ resourceDefinition.setRequiredPermission(requiredPermission);
+ final String[] tags = invokeAnnotationMethod(apiResource, "tags");
+ resourceDefinition.setTags(tags);
+ final Boolean requiredAccessDomain =
+ invokeAnnotationMethod(apiResource, "requiredAccessDomain");
+ resourceDefinition.setRequiredAccessDomain(requiredAccessDomain);
+
+ final RequestMethod[] requestMethods =
+ invokeAnnotationMethod(apiResource, "method");
+ final List methodNames = new ArrayList<>();
+ for (final RequestMethod requestMethod : requestMethods) {
+ methodNames.add(requestMethod.name());
+ }
+ resourceDefinition.setHttpMethod(StrUtil.join(",", methodNames));
+
+ final String localMacAddress = NetUtil.getLocalhostStr();
+ resourceDefinition.setIpAddress(
+ localMacAddress == null ? "" : localMacAddress);
+ resourceDefinition.setCreateTime(LocalDateTime.now());
+ return resourceDefinition;
+ }
+
+ @SuppressWarnings("unchecked")
+ private T invokeAnnotationMethod(
+ final Annotation apiResource, final String methodName) {
+ try {
+ final Class extends Annotation> annotationType =
+ apiResource.annotationType();
+ final Method method = annotationType.getMethod(methodName);
+ return (T) method.invoke(apiResource);
+ } catch (NoSuchMethodException | IllegalAccessException
+ | InvocationTargetException e) {
+ log.error("fail to scan api resources!", e);
+ throw new RuntimeException("fail to scan api resources!", e);
+ }
+ }
+
+ private String getControllerClassRequestPath(final Class> clazz) {
+ String result = "";
+
+ final ApiResource controllerRequestMapping =
+ clazz.getDeclaredAnnotation(ApiResource.class);
+ if (controllerRequestMapping != null) {
+ final String[] paths = controllerRequestMapping.path();
+ if (paths.length > 0) {
+ result = paths[0];
+ } else {
+ result = "";
+ }
}
- private Annotation getOnMethod(final Method method) {
- Annotation annotation = null;
+ return result;
+ }
- final GetResource getResource = method.getAnnotation(GetResource.class);
+ private String getControllerClassPrefix(final String className) {
+ final int controllerIndex = className.indexOf("Controller");
+ if (controllerIndex == -1) {
+ throw new IllegalArgumentException(
+ "Controller naming error, " + "should ends with Controller!");
+ }
+ return className.substring(0, controllerIndex);
+ }
- if (getResource != null && !getResource.ignore()) {
- annotation = getResource;
- }
+ private Annotation getOnMethod(final Method method) {
+ Annotation annotation = null;
- final PostResource postResource = method.getAnnotation(PostResource.class);
+ final GetResource getResource = method.getAnnotation(GetResource.class);
- if (postResource != null && !postResource.ignore()) {
- annotation = postResource;
- }
+ if (getResource != null && !getResource.ignore()) {
+ annotation = getResource;
+ }
- return annotation;
+ final PostResource postResource = method.getAnnotation(PostResource.class);
+
+ if (postResource != null && !postResource.ignore()) {
+ annotation = postResource;
}
+
+ return annotation;
+ }
}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/scanner/package-info.java b/backend-server/application/src/main/java/com/apitable/shared/component/scanner/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..763f59938fef26533c69f19f04d32f789cd16bbd
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/shared/component/scanner/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * APITable
+ * Copyright (C) 2022 APITable Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ *
+ * @author Chambers
+ */
+package com.apitable.shared.component.scanner;
diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/RedisConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/RedisConfig.java
index b5c46c276d687a0bf15eb1f557e0196b6bff1952..47d94927605b0a64a230962b9dd01a7bd0d55cb5 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/config/RedisConfig.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/config/RedisConfig.java
@@ -18,11 +18,6 @@
package com.apitable.shared.config;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import cn.hutool.core.lang.Dict;
-import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
@@ -30,16 +25,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import lombok.extern.slf4j.Slf4j;
-import com.apitable.core.constants.RedisConstants;
-
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.integration.redis.util.RedisLockRegistry;
-import org.springframework.lang.Nullable;
/**
*
@@ -65,7 +57,7 @@ public class RedisConfig {
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(factory);
- template.setKeySerializer(new MagicalKeyStringRedisSerializer(StandardCharsets.UTF_8));
+ template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(json());
template.afterPropertiesSet();
return template;
@@ -75,30 +67,4 @@ public class RedisConfig {
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "apitable:concurrent");
}
-
- private static class MagicalKeyStringRedisSerializer extends StringRedisSerializer {
-
- public MagicalKeyStringRedisSerializer(Charset charset) {
- super(charset);
- }
-
- @Override
- public String deserialize(@Nullable byte[] bytes) {
- return super.deserialize(bytes);
- }
-
- @Override
- public byte[] serialize(@Nullable String string) {
- // replace magic value
- string = StrUtil.format(string, this.getAllMagicalValue());
- return super.serialize(string);
- }
-
- private Dict getAllMagicalValue() {
- String env = System.getenv("ENV");
- log.info("Magical Key String Redis Serializer Load Environment: {}", env);
- return Dict.create().set(RedisConstants.REDIS_ENV, env);
- }
-
- }
}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/ServerConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/ServerConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..e94275aa85c9aef60fc4abbb168247fbbd4f88ef
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/shared/config/ServerConfig.java
@@ -0,0 +1,43 @@
+package com.apitable.shared.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.util.Arrays;
+import java.util.TimeZone;
+
+/**
+ * server config
+ *
+ * @author Shawn Deng
+ */
+@Component
+@Slf4j
+public class ServerConfig implements InitializingBean {
+
+ @Value("${DEFAULT_TIME_ZONE:UTC}")
+ private String timeZone;
+
+ public ZoneId getTimeZoneId() {
+ return ZoneId.of(timeZone);
+ }
+
+ public ZoneOffset getTimeZone() {
+ return getTimeZoneId().getRules().getOffset(Instant.now());
+ }
+
+ @Override
+ public void afterPropertiesSet() {
+ String[] availableIDs = TimeZone.getAvailableIDs();
+ boolean validate = Arrays.stream(availableIDs).anyMatch(zoneId -> zoneId.equals(timeZone));
+ if (!validate) {
+ throw new IllegalArgumentException("Invalid TimeZone Input : " + timeZone);
+ }
+ log.info("Server Default Region TimeZone: " + timeZone);
+ }
+}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/SleuthConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/SleuthConfig.java
index 47d4b4ebb6839d8219c40132227b867bd4f6f101..d20aa677b33479ccbb977ea95e4c8ce0a7954cce 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/config/SleuthConfig.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/config/SleuthConfig.java
@@ -18,8 +18,7 @@
package com.apitable.shared.config;
-import brave.http.HttpRequestParser;
-
+import org.springframework.cloud.sleuth.http.HttpRequestParser;
import org.springframework.cloud.sleuth.instrument.web.HttpClientRequestParser;
import org.springframework.cloud.sleuth.instrument.web.HttpServerRequestParser;
import org.springframework.context.annotation.Bean;
@@ -32,11 +31,10 @@ import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class SleuthConfig {
- @Bean(name = { HttpClientRequestParser.NAME, HttpServerRequestParser.NAME})
+ @Bean(name = { HttpClientRequestParser.NAME, HttpServerRequestParser.NAME })
HttpRequestParser sleuthHttpServerRequestParser() {
- return (req, context, span) -> {
- HttpRequestParser.DEFAULT.parse(req, context, span);
- String url = req.url();
+ return (request, context, span) -> {
+ String url = request.url();
if (url != null) {
span.tag("http.url", url);
}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java b/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java
index dd128adc4a2770167e844513e426ed06c59e31aa..430179e9b03a884c9928cacce8361c1ffa068861 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java
@@ -31,9 +31,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import static com.apitable.shared.config.properties.ConstProperties.PREFIX_CONST;
/**
- *
- * server constants properties
- *
+ * server constants properties.
*
* @author Chambers
*/
@@ -41,100 +39,83 @@ import static com.apitable.shared.config.properties.ConstProperties.PREFIX_CONST
@ConfigurationProperties(prefix = PREFIX_CONST)
public class ConstProperties {
+ /** */
public static final String PREFIX_CONST = "const";
+ /** */
private String languageTag = "zh-CN";
+ /** */
private String serverDomain;
+ /** */
private String callbackDomain;
+ /** */
private String workbenchUrl = "/workbench";
/**
- * Whether to create a picture audit record
+ * Whether to create a picture audit record.
*/
private boolean ossImageAuditCreatable = false;
/**
- * OSS bucket configuration
+ * OSS bucket configuration.
*/
private Map ossBuckets;
/**
- * api document avoid validate token
- */
- private String loginToken = "BornForFuture";
-
- /**
- * Official default avatar list
- * @deprecated open-source
- */
- @Deprecated
- private String defaultAvatarList;
-
- /**
- * Template space, the templates created in this space will become official templates,
- * and there is no upper limit for the number of templates
+ * Template space, the templates created in this space
+ * * will become official templates,
+ * and there is no upper limit for the number of templates.
*/
private String templateSpace = "";
/**
- * Template ID referenced by new space by default
+ * Template ID referenced by new space by default.
*/
private String quoteTemplateId = "tpll8mltwrZMT";
/**
- * English template ID referenced by default in new space
+ * English template ID referenced by default in new space.
*/
private String quoteEnTemplateId = "tpll8mltwrZMT";
/**
- * wechat-mp reply template id
- * @deprecated open-source
- */
- @Deprecated
- private String qrCodeReplyId;
-
- /**
- * dingtalk subscription information table id
+ * dingtalk subscription information table id.
*/
private String dingTalkOrderDatasheet;
/**
- * Do DingTalk self-built apps need to restore the directory tree?
+ * *
+ * @return OssBucketInfo
*/
- private Boolean dingTalkContactWithTree = false;
-
public OssBucketInfo getOssBucketByAsset() {
- return Optional.ofNullable(ossBuckets).orElseGet(HashMap::new).getOrDefault(BucketKey.VK_ASSETS_LTD, new OssBucketInfo());
+ return Optional.ofNullable(ossBuckets).orElseGet(HashMap::new)
+ .getOrDefault(BucketKey.VK_ASSETS_LTD, new OssBucketInfo());
}
- public OssBucketInfo getOssBucketByPublicAsset() {
- return Optional.ofNullable(ossBuckets).orElseGet(HashMap::new).getOrDefault(BucketKey.VK_PUBLIC_ASSETS_LTD, new OssBucketInfo());
+ /**
+ * *
+ * @return String
+ */
+ public String defaultServerDomain() {
+ return ReUtil.replaceAll(serverDomain, "http://|https://",
+ StrUtil.EMPTY);
}
public enum BucketKey {
- // old resource bucket
- // It will be temporarily reserved during the transformation of the front-end direct transmission, and will be invalid when the transformation is completed.
- @Deprecated
+ /** */
VK_ASSETS_LTD,
- // new open bucket
- VK_PUBLIC_ASSETS_LTD,
}
@Data
public static class OssBucketInfo {
-
+ /** */
private String resourceUrl = "";
-
+ /** */
private String bucketName;
-
+ /** */
private String type;
}
-
-
- public String defaultServerDomain() {
- return ReUtil.replaceAll(serverDomain, "http://|https://", StrUtil.EMPTY);
- }
}
diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/properties/package-info.java b/backend-server/application/src/main/java/com/apitable/shared/config/properties/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab3c6a8d60988d20e85922038bafe977626c75fd
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/shared/config/properties/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * APITable
+ * Copyright (C) 2022 APITable Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ *
+ * @author Chambers
+ */
+package com.apitable.shared.config.properties;
diff --git a/backend-server/application/src/main/java/com/apitable/shared/listener/ApplicationReadyEventListener.java b/backend-server/application/src/main/java/com/apitable/shared/listener/ApplicationReadyEventListener.java
index a4bb8beef7c643bcc156f958dfbf33f4b4669dd4..c6edeb6e8d7ca0e06a1378129ba186ddcf24fe40 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/listener/ApplicationReadyEventListener.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/listener/ApplicationReadyEventListener.java
@@ -18,18 +18,15 @@
package com.apitable.shared.listener;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import lombok.extern.slf4j.Slf4j;
-
import com.apitable.shared.component.LanguageManager;
-
+import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
-import static com.apitable.shared.constants.TimeZoneConstants.DEFAULT_TIME_ZONE;
+import java.time.ZoneOffset;
+import java.util.Locale;
+import java.util.TimeZone;
/**
*
@@ -44,7 +41,7 @@ public class ApplicationReadyEventListener implements ApplicationListener
* notification creation listener
diff --git a/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java b/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java
index 54b746fb55a1eca1475d230dfffd109410322a95..5406f01517f4c5c726cb611c1058ae24b1c675eb 100644
--- a/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java
+++ b/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java
@@ -18,7 +18,6 @@
package com.apitable.shared.util;
-import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
@@ -40,11 +39,6 @@ public class DateHelper {
return ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
}
- public static LocalDateTime getStartTimeOfMonth() {
- LocalDate date = LocalDate.now();
- return LocalDateTime.of(date.getYear(), date.getMonth(), 1, 0, 0);
- }
-
/**
* format the time according to the incoming format
*
diff --git a/backend-server/application/src/main/java/com/apitable/space/assembler/SpaceAssembler.java b/backend-server/application/src/main/java/com/apitable/space/assembler/SpaceAssembler.java
new file mode 100644
index 0000000000000000000000000000000000000000..c08ee36e0ffd7331375b7140b5fae74fe1fd4286
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/space/assembler/SpaceAssembler.java
@@ -0,0 +1,33 @@
+package com.apitable.space.assembler;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.apitable.interfaces.social.model.SocialConnectInfo;
+import com.apitable.space.dto.SpaceDTO;
+import com.apitable.space.vo.SpaceSocialConfig;
+import com.apitable.space.vo.SpaceVO;
+
+public class SpaceAssembler {
+
+ public static SpaceVO toVO(SpaceDTO spaceDTO) {
+ SpaceVO spaceVO = new SpaceVO();
+ spaceVO.setSpaceId(spaceDTO.getSpaceId());
+ spaceVO.setName(spaceDTO.getName());
+ spaceVO.setLogo(spaceDTO.getLogo());
+ spaceVO.setPoint(spaceDTO.getPoint());
+ spaceVO.setAdmin(spaceDTO.getAdmin());
+ spaceVO.setPreDeleted(spaceDTO.getPreDeleted());
+ return spaceVO;
+ }
+
+ public static SpaceSocialConfig toSocialConfig(SocialConnectInfo socialConnectInfo) {
+ SpaceSocialConfig socialConfig = new SpaceSocialConfig();
+ if (ObjectUtil.isNotNull(socialConnectInfo)) {
+ socialConfig.setEnabled(socialConnectInfo.isEnabled());
+ socialConfig.setPlatform(socialConnectInfo.getPlatform());
+ socialConfig.setAppType(socialConnectInfo.getAppType());
+ socialConfig.setAuthMode(socialConnectInfo.getAuthMode());
+ socialConfig.setContactSyncing(socialConnectInfo.contactSyncing());
+ }
+ return socialConfig;
+ }
+}
diff --git a/backend-server/application/src/main/java/com/apitable/space/dto/SpaceDTO.java b/backend-server/application/src/main/java/com/apitable/space/dto/SpaceDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..4259e4d387d7acd7d9ff2eb20d345afb09a29abf
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/space/dto/SpaceDTO.java
@@ -0,0 +1,19 @@
+package com.apitable.space.dto;
+
+import lombok.Data;
+
+@Data
+public class SpaceDTO {
+
+ private String spaceId;
+
+ private String name;
+
+ private String logo;
+
+ private Boolean point;
+
+ private Boolean admin;
+
+ private Boolean preDeleted;
+}
diff --git a/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java b/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java
index e211229b2430385710c82eb28e033ab4def08015..ba7e96afc08523a3c93bbf1281d66f61feff6046 100644
--- a/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java
+++ b/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java
@@ -18,13 +18,13 @@
package com.apitable.space.mapper;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.apitable.space.dto.MapDTO;
import com.apitable.space.dto.BaseSpaceInfoDTO;
+import com.apitable.space.dto.MapDTO;
import com.apitable.space.dto.SpaceAdminInfoDTO;
-import com.apitable.space.vo.SpaceVO;
+import com.apitable.space.dto.SpaceDTO;
import com.apitable.space.entity.SpaceEntity;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
@@ -61,7 +61,7 @@ public interface SpaceMapper extends BaseMapper {
* @return the user's space infos.
*/
@InterceptorIgnore(illegalSql = "true")
- List selectListByUserId(@Param("userId") Long userId);
+ List selectListByUserId(@Param("userId") Long userId);
/**
* @param userId user id
diff --git a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java
index 07e06d43417a70c33d3565c6a36987ceeb255b3e..09507e45a56274022ed80a8355da6343f26f7dd6 100644
--- a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java
+++ b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java
@@ -18,19 +18,6 @@
package com.apitable.space.service.impl;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Dict;
@@ -39,12 +26,11 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
-import lombok.extern.slf4j.Slf4j;
-
import com.apitable.asset.service.IAssetService;
import com.apitable.base.enums.DatabaseException;
+import com.apitable.core.util.ExceptionUtil;
+import com.apitable.core.util.SpringContextHolder;
+import com.apitable.core.util.SqlTool;
import com.apitable.interfaces.billing.facade.EntitlementServiceFacade;
import com.apitable.interfaces.billing.model.SubscriptionFeature;
import com.apitable.interfaces.billing.model.SubscriptionInfo;
@@ -83,14 +69,9 @@ import com.apitable.shared.holder.NotificationRenderFieldHolder;
import com.apitable.shared.listener.event.AuditSpaceEvent;
import com.apitable.shared.listener.event.AuditSpaceEvent.AuditSpaceArg;
import com.apitable.shared.util.IdUtil;
+import com.apitable.space.assembler.SpaceAssembler;
import com.apitable.space.assembler.SubscribeAssembler;
-import com.apitable.space.dto.ControlStaticsDTO;
-import com.apitable.space.dto.DatasheetStaticsDTO;
-import com.apitable.space.dto.GetSpaceListFilterCondition;
-import com.apitable.space.dto.MapDTO;
-import com.apitable.space.dto.NodeTypeStaticsDTO;
-import com.apitable.space.dto.SpaceAdminInfoDTO;
-import com.apitable.space.dto.SpaceCapacityUsedInfo;
+import com.apitable.space.dto.*;
import com.apitable.space.entity.SpaceEntity;
import com.apitable.space.enums.AuditSpaceAction;
import com.apitable.space.enums.SpaceException;
@@ -98,17 +79,8 @@ import com.apitable.space.enums.SpaceResourceGroupCode;
import com.apitable.space.mapper.SpaceMapper;
import com.apitable.space.mapper.SpaceMemberRoleRelMapper;
import com.apitable.space.ro.SpaceUpdateOpRo;
-import com.apitable.space.service.IInvitationService;
-import com.apitable.space.service.ISpaceInviteLinkService;
-import com.apitable.space.service.ISpaceRoleService;
-import com.apitable.space.service.ISpaceService;
-import com.apitable.space.service.IStaticsService;
-import com.apitable.space.vo.SpaceGlobalFeature;
-import com.apitable.space.vo.SpaceInfoVO;
-import com.apitable.space.vo.SpaceSocialConfig;
-import com.apitable.space.vo.SpaceSubscribeVo;
-import com.apitable.space.vo.SpaceVO;
-import com.apitable.space.vo.UserSpaceVo;
+import com.apitable.space.service.*;
+import com.apitable.space.vo.*;
import com.apitable.template.service.ITemplateService;
import com.apitable.user.entity.UserEntity;
import com.apitable.user.service.IUserService;
@@ -118,25 +90,27 @@ import com.apitable.workspace.enums.IdRulePrefixEnum;
import com.apitable.workspace.enums.NodeType;
import com.apitable.workspace.service.INodeService;
import com.apitable.workspace.service.INodeShareSettingService;
-import com.apitable.core.util.ExceptionUtil;
-import com.apitable.core.util.SpringContextHolder;
-import com.apitable.core.util.SqlTool;
-
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
import static com.apitable.organization.enums.OrganizationException.CREATE_MEMBER_ERROR;
import static com.apitable.organization.enums.OrganizationException.NOT_EXIST_MEMBER;
import static com.apitable.shared.constants.NotificationConstants.NEW_SPACE_NAME;
import static com.apitable.shared.constants.NotificationConstants.OLD_SPACE_NAME;
-import static com.apitable.space.enums.SpaceException.NO_ALLOW_OPERATE;
-import static com.apitable.space.enums.SpaceException.SPACE_NOT_EXIST;
-import static com.apitable.space.enums.SpaceException.SPACE_QUIT_FAILURE;
-import static com.apitable.workspace.enums.PermissionException.CAN_OP_MAIN_ADMIN;
-import static com.apitable.workspace.enums.PermissionException.MEMBER_NOT_IN_SPACE;
-import static com.apitable.workspace.enums.PermissionException.SET_MAIN_ADMIN_FAIL;
-import static com.apitable.workspace.enums.PermissionException.TRANSFER_SELF;
+import static com.apitable.space.enums.SpaceException.*;
+import static com.apitable.workspace.enums.PermissionException.*;
@Service
@Slf4j
@@ -411,30 +385,39 @@ public class SpaceServiceImpl extends ServiceImpl impl
@Override
public List getSpaceListByUserId(Long userId, GetSpaceListFilterCondition condition) {
- List list = baseMapper.selectListByUserId(userId);
- if (CollUtil.isEmpty(list)) {
- return list;
+ List spaceDTOList = baseMapper.selectListByUserId(userId);
+ if (CollUtil.isEmpty(spaceDTOList)) {
+ return Collections.emptyList();
+ }
+ if (condition != null && BooleanUtil.isTrue(condition.getManageable())) {
+ spaceDTOList = spaceDTOList.stream()
+ .filter(SpaceDTO::getAdmin)
+ .collect(Collectors.toList());
}
- Map spaceMaps = list.stream().collect(Collectors.toMap(SpaceVO::getSpaceId, v -> v, (k1, k2) -> k1));
+ if (CollUtil.isEmpty(spaceDTOList)) {
+ return Collections.emptyList();
+ }
+ Map spaceMaps = spaceDTOList.stream().collect(Collectors.toMap(SpaceDTO::getSpaceId, v -> v, (k1, k2) -> k1));
List spaceIds = new ArrayList<>(spaceMaps.keySet());
// get space domains
Map spaceDomains = socialServiceFacade.getDomainNameMap(spaceIds);
// batch query subscriptions
Map spacePlanFeatureMap = entitlementServiceFacade.getSpaceSubscriptions(spaceIds);
// setting information
- spaceMaps.forEach((spaceId, spaceVO) -> {
- SubscriptionFeature planFeature = spacePlanFeatureMap.get(spaceId);
- spaceVO.setMaxSeat(planFeature.getSeat().getValue());
- spaceVO.setSpaceDomain(spaceDomains.get(spaceId));
- });
- if (condition != null) {
- if (BooleanUtil.isTrue(condition.getManageable())) {
- return list.stream()
- .filter(v -> v.getAdmin().equals(condition.getManageable()))
- .collect(Collectors.toList());
+ List resultList = new ArrayList<>();
+ spaceMaps.forEach((spaceId, spaceDTO) -> {
+ SpaceVO spaceVO = SpaceAssembler.toVO(spaceDTO);
+ SocialConnectInfo socialConnectInfo = socialServiceFacade.getConnectInfo(spaceId);
+ SpaceSocialConfig socialConfig = SpaceAssembler.toSocialConfig(socialConnectInfo);
+ spaceVO.setSocial(socialConfig);
+ if (spacePlanFeatureMap.containsKey(spaceId)) {
+ SubscriptionFeature planFeature = spacePlanFeatureMap.get(spaceId);
+ spaceVO.setMaxSeat(planFeature.getSeat().getValue());
+ spaceVO.setSpaceDomain(spaceDomains.get(spaceId));
}
- }
- return list;
+ resultList.add(spaceVO);
+ });
+ return resultList;
}
@Override
@@ -505,8 +488,7 @@ public class SpaceServiceImpl extends ServiceImpl impl
vo.setCreatorName(ownerMember.getMemberName());
vo.setCreatorAvatar(ownerMember.getAvatar());
vo.setIsCreatorNameModified(ownerMember.getIsSocialNameModified() > 0);
- }
- else {
+ } else {
MemberDTO creatorMember = memberMapper.selectDtoByMemberId(entity.getCreator());
if (creatorMember != null) {
vo.setCreatorName(creatorMember.getMemberName());
@@ -550,8 +532,7 @@ public class SpaceServiceImpl extends ServiceImpl impl
spaceCapacityUsedInfo.setCurrentBundleCapacityUsedSizes(capacityUsedSize);
// Because the package capacity is preferred, the complimentary attachment capacity has been used to be 0.
spaceCapacityUsedInfo.setGiftCapacityUsedSizes(0L);
- }
- else {
+ } else {
spaceCapacityUsedInfo.setCurrentBundleCapacityUsedSizes(planCapacity);
// complimentary attachment capacity
Long giftCapacity = subscriptionInfo.getGiftCapacity().getValue();
@@ -559,8 +540,7 @@ public class SpaceServiceImpl extends ServiceImpl impl
// the used complimentary attachment capacity is equal to the size of the complimentary assert capacity.
if (capacityUsedSize > subscriptionInfo.getTotalCapacity().getValue()) {
spaceCapacityUsedInfo.setGiftCapacityUsedSizes(giftCapacity);
- }
- else {
+ } else {
// gift capacity used left
spaceCapacityUsedInfo.setGiftCapacityUsedSizes(capacityUsedSize - planCapacity);
}
@@ -620,8 +600,7 @@ public class SpaceServiceImpl extends ServiceImpl impl
// check whether the mobile phone verification code is passed
ValidateTarget target = ValidateTarget.create(dto.getMobile(), dto.getAreaCode());
ValidateCodeProcessorManage.me().findValidateCodeProcessor(ValidateCodeType.SMS).verifyIsPass(target.getRealTarget());
- }
- else if (dto.getEmail() != null) {
+ } else if (dto.getEmail() != null) {
// check whether the sms verification code is passed
ValidateTarget target = ValidateTarget.create(dto.getEmail());
ValidateCodeProcessorManage.me().findValidateCodeProcessor(ValidateCodeType.EMAIL).verifyIsPass(target.getRealTarget());
@@ -759,8 +738,7 @@ public class SpaceServiceImpl extends ServiceImpl impl
if (linkId.startsWith(IdRulePrefixEnum.SHARE.getIdRulePrefixEnum())) {
// sharing node
return iNodeShareSettingService.getSpaceId(linkId);
- }
- else {
+ } else {
// template
return iTemplateService.getSpaceId(linkId);
}
diff --git a/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java b/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java
index 12d629d885d26d98d46309a5251b1d4589ca576c..deb3f1e04996fc624db9c9f02f91dbd598ea7634 100644
--- a/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java
+++ b/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java
@@ -18,41 +18,39 @@
package com.apitable.space.service.impl;
-import java.text.SimpleDateFormat;
-import java.time.LocalDateTime;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrSpliter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
-import lombok.extern.slf4j.Slf4j;
-
import com.apitable.control.infrastructure.ControlIdBuilder;
import com.apitable.control.infrastructure.ControlType;
import com.apitable.control.mapper.ControlMapper;
import com.apitable.control.model.ControlTypeDTO;
-import com.apitable.space.mapper.StaticsMapper;
+import com.apitable.core.util.SqlTool;
+import com.apitable.shared.util.DateHelper;
import com.apitable.space.dto.ControlStaticsDTO;
import com.apitable.space.dto.DatasheetStaticsDTO;
import com.apitable.space.dto.NodeStaticsDTO;
import com.apitable.space.dto.NodeTypeStaticsDTO;
+import com.apitable.space.mapper.StaticsMapper;
import com.apitable.space.service.IStaticsService;
import com.apitable.workspace.mapper.NodeMapper;
-import com.apitable.shared.util.DateHelper;
-import com.apitable.core.util.SqlTool;
-
+import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
-import static com.apitable.shared.constants.DateFormatConstants.YEARS_MONTH_PATTERN;
+import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
import static com.apitable.core.constants.RedisConstants.GENERAL_STATICS;
+import static com.apitable.shared.constants.DateFormatConstants.YEARS_MONTH_PATTERN;
+import static java.time.temporal.TemporalAdjusters.firstDayOfMonth;
/**
*
@@ -113,7 +111,7 @@ public class StaticsServiceImpl implements IStaticsService {
@Override
public Long getCurrentMonthApiUsageUntilYesterday(String spaceId) {
// If it is the first day of this month, 0 will be returned directly
- if (ObjectUtil.equals(DateUtil.date(new Date()).getDate(), 1)) {
+ if (ObjectUtil.equals(LocalDateTime.now().getDayOfMonth(), 1)) {
return 0L;
} else {
// Get the API usage cache of this month before today
@@ -152,7 +150,8 @@ public class StaticsServiceImpl implements IStaticsService {
id = staticsMapper.selectMaxId();
}
else {
- id = staticsMapper.selectApiUsageMinIdByCreatedAt(lastMonthMinId, DateHelper.getStartTimeOfMonth());
+ LocalDateTime startDayOfMonth = now.with(firstDayOfMonth());
+ id = staticsMapper.selectApiUsageMinIdByCreatedAt(lastMonthMinId, startDayOfMonth);
}
// Keep the cache of the month
redisTemplate.opsForValue().set(key, id, 33, TimeUnit.DAYS);
diff --git a/backend-server/application/src/main/java/com/apitable/space/vo/SpaceVO.java b/backend-server/application/src/main/java/com/apitable/space/vo/SpaceVO.java
index 3874cdbe89b83dbfe1734279018bb6d25187f797..afb3e011b05417b8868753ee88c3e832feb76ea7 100644
--- a/backend-server/application/src/main/java/com/apitable/space/vo/SpaceVO.java
+++ b/backend-server/application/src/main/java/com/apitable/space/vo/SpaceVO.java
@@ -18,6 +18,7 @@
package com.apitable.space.vo;
+import com.apitable.shared.support.serializer.NullNumberSerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -58,21 +59,17 @@ public class SpaceVO {
@JsonSerialize(nullsUsing = NullBooleanSerializer.class)
private Boolean admin;
- @ApiModelProperty(value = "Whether it is a paid space", example = "false", position = 6)
- @JsonSerialize(nullsUsing = NullBooleanSerializer.class)
- private Boolean charge;
-
@ApiModelProperty(value = "Whether it is in pre deletion status", example = "false", position = 7)
@JsonSerialize(nullsUsing = NullBooleanSerializer.class)
private Boolean preDeleted;
@ApiModelProperty(value = "Maximum total number of subscription plan members", position = 8)
+ @JsonSerialize(nullsUsing = NullNumberSerializer.class)
private Long maxSeat;
@ApiModelProperty(value = "Space domain name", position = 9)
private String spaceDomain;
- @Deprecated
@ApiModelProperty(value = "Third party integration binding information", position = 10)
private SpaceSocialConfig social;
}
diff --git a/backend-server/application/src/main/java/com/apitable/template/mapper/TemplatePropertyRelMapper.java b/backend-server/application/src/main/java/com/apitable/template/mapper/TemplatePropertyRelMapper.java
index 715280a6b12ad76d663c59e8fc931571f6ef2bd2..53ade84ed62695a124d544ce733177de49ac28eb 100644
--- a/backend-server/application/src/main/java/com/apitable/template/mapper/TemplatePropertyRelMapper.java
+++ b/backend-server/application/src/main/java/com/apitable/template/mapper/TemplatePropertyRelMapper.java
@@ -20,12 +20,11 @@ package com.apitable.template.mapper;
import java.util.List;
+import com.apitable.template.entity.TemplatePropertyRelEntity;
+import com.apitable.template.model.TemplatePropertyRelDto;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
-import com.apitable.template.model.TemplatePropertyRelDto;
-import com.apitable.template.entity.TemplatePropertyRelEntity;
-
/**
*
* Template Property Rel Mapper
@@ -44,14 +43,9 @@ public interface TemplatePropertyRelMapper extends BaseMapper entities);
/**
- * Query template id list by property id
- */
- List selectTemplateIdsByPropertyId(@Param("propertyId") Long propertyId);
-
- /**
- * Batch delete by id list
+ * Query template id list by property code
*/
- int deleteBatchIn(@Param("propertyIds") List propertyIds);
+ List selectTemplateIdsByPropertyCode(@Param("propertyCode") String propertyCode);
/**
* Query template ids by property id list
diff --git a/backend-server/application/src/main/java/com/apitable/template/service/ITemplatePropertyService.java b/backend-server/application/src/main/java/com/apitable/template/service/ITemplatePropertyService.java
index 4edda1f2159a6a20fa406816baeee67a62181296..0f0df07851b38486dc11bf28bbc284fc76eedabc 100644
--- a/backend-server/application/src/main/java/com/apitable/template/service/ITemplatePropertyService.java
+++ b/backend-server/application/src/main/java/com/apitable/template/service/ITemplatePropertyService.java
@@ -22,13 +22,12 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import com.baomidou.mybatisplus.extension.service.IService;
-
import com.apitable.shared.cache.bean.CategoryDto;
+import com.apitable.template.entity.TemplatePropertyEntity;
import com.apitable.template.enums.TemplatePropertyType;
import com.apitable.template.model.TemplatePropertyDto;
import com.apitable.template.model.TemplatePropertyRelDto;
-import com.apitable.template.entity.TemplatePropertyEntity;
+import com.baomidou.mybatisplus.extension.service.IService;
/**
*
@@ -42,11 +41,6 @@ public interface ITemplatePropertyService extends IService getTemplatePropertiesWithLangAndOrder(TemplatePropertyType type, String lang);
- /**
- * Get property id by property code and type
- */
- Long getIdByCodeAndType(String code, TemplatePropertyType type);
-
/**
* Get template id list by property code and type
*/
diff --git a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplatePropertyServiceImpl.java b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplatePropertyServiceImpl.java
index 0c4faacf3870535a66c8cbc447c5cc918d9d0b89..cdf46ca99cbebe27196753e5cec15cc15911fa94 100644
--- a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplatePropertyServiceImpl.java
+++ b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplatePropertyServiceImpl.java
@@ -19,7 +19,6 @@
package com.apitable.template.service.impl;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -28,9 +27,6 @@ import java.util.stream.Collectors;
import javax.annotation.Resource;
import cn.hutool.core.collection.CollUtil;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import lombok.extern.slf4j.Slf4j;
-
import com.apitable.shared.cache.bean.CategoryDto;
import com.apitable.shared.component.LanguageManager;
import com.apitable.template.entity.TemplatePropertyEntity;
@@ -41,6 +37,8 @@ import com.apitable.template.model.TemplateKeyWordSearchDto;
import com.apitable.template.model.TemplatePropertyDto;
import com.apitable.template.model.TemplatePropertyRelDto;
import com.apitable.template.service.ITemplatePropertyService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -65,18 +63,9 @@ public class TemplatePropertyServiceImpl extends ServiceImpl getTemplateIdsByPropertyCodeAndType(String code, TemplatePropertyType type) {
- Long propertyId = getIdByCodeAndType(code, type);
- if (propertyId != null) {
- return propertyRelMapper.selectTemplateIdsByPropertyId(propertyId);
- }
- return Collections.emptyList();
+ return propertyRelMapper.selectTemplateIdsByPropertyCode(code);
}
@Override
diff --git a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java
index e1da2007a6da4fcd6b1fb0c01ea9c78a871e085a..deac86327094674c2d229594e1c1f421848ebc1f 100644
--- a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java
+++ b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java
@@ -37,13 +37,13 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
+import com.apitable.widget.service.IWidgetService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import com.apitable.base.enums.DatabaseException;
import com.apitable.control.infrastructure.role.ControlRoleManager;
import com.apitable.control.infrastructure.role.RoleConstants.Node;
-import com.apitable.interfaces.widget.facade.WidgetServiceFacade;
import com.apitable.shared.cache.bean.CategoryDto;
import com.apitable.shared.cache.bean.RecommendConfig;
import com.apitable.shared.cache.bean.RecommendConfig.AlbumGroup;
@@ -142,7 +142,7 @@ public class TemplateServiceImpl extends ServiceImpl update(@RequestBody @Valid UserOpRo param) {
- ExceptionUtil.isTrue(StrUtil.isNotBlank(param.getAvatar()) || StrUtil.isNotBlank(param.getNickName())
+ ExceptionUtil.isTrue(StrUtil.isNotBlank(param.getAvatar()) || StrUtil.isNotBlank(param.getNickName()) || ObjectUtil.isNotNull(param.getAvatarColor())
|| StrUtil.isNotBlank(param.getLocale()), ParameterException.NO_ARG);
Long userId = SessionContext.getUserId();
iUserService.edit(userId, param);
diff --git a/backend-server/application/src/main/java/com/apitable/user/entity/UserEntity.java b/backend-server/application/src/main/java/com/apitable/user/entity/UserEntity.java
index 296ce5c151a2fa5546595b51ecef0494985f9935..0fbe9fb2cd2fd6cfd0d1bcd116869b40c2f3eeb5 100644
--- a/backend-server/application/src/main/java/com/apitable/user/entity/UserEntity.java
+++ b/backend-server/application/src/main/java/com/apitable/user/entity/UserEntity.java
@@ -83,13 +83,11 @@ public class UserEntity implements Serializable {
*/
private String password;
- @TableField(updateStrategy = FieldStrategy.IGNORED)
/**
* Avatar
*/
private String avatar;
- @TableField(updateStrategy = FieldStrategy.IGNORED)
/**
* default avatar color number
*/
diff --git a/backend-server/application/src/main/java/com/apitable/user/mapper/UserMapper.java b/backend-server/application/src/main/java/com/apitable/user/mapper/UserMapper.java
index 95dbbbe23ae7b409dfe28aa09d3e646773ef2ef4..50ab880a8ce5413f21836451cfd0fefbbfeaa8d7 100644
--- a/backend-server/application/src/main/java/com/apitable/user/mapper/UserMapper.java
+++ b/backend-server/application/src/main/java/com/apitable/user/mapper/UserMapper.java
@@ -185,6 +185,15 @@ public interface UserMapper extends BaseMapper {
* */
int resetUserById(@Param("userId") Long userId);
+ /**
+ * update user avatar information
+ *
+ * @param userId User ID
+ * @param avatar User avatar
+ * @param color User default avatar color number
+ */
+ int updateUserAvatarInfo(@Param("userId") Long userId, @Param("avatar") String avatar, @Param("color") Integer color);
+
/**
* Batch query member email
*
diff --git a/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java b/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java
index a234627783de7397eb0ebd26d24dcb53ad2a78eb..4cabb9402685416e3cc3be1054b54df60e8e4283 100644
--- a/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java
+++ b/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java
@@ -41,13 +41,12 @@ import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
-import com.google.common.collect.Lists;
-import lombok.extern.slf4j.Slf4j;
-
import com.apitable.asset.service.IAssetService;
import com.apitable.base.enums.DatabaseException;
+import com.apitable.core.exception.BusinessException;
+import com.apitable.core.util.ExceptionUtil;
+import com.apitable.core.util.HttpContextUtil;
+import com.apitable.core.util.SqlTool;
import com.apitable.interfaces.social.enums.SocialNameModified;
import com.apitable.interfaces.social.facade.SocialServiceFacade;
import com.apitable.interfaces.social.model.SocialUserBind;
@@ -74,13 +73,11 @@ import com.apitable.shared.component.TaskManager;
import com.apitable.shared.component.notification.INotificationFactory;
import com.apitable.shared.component.notification.NotificationManager;
import com.apitable.shared.component.notification.NotificationTemplateId;
-import com.apitable.shared.config.properties.ConstProperties;
import com.apitable.shared.constants.LanguageConstants;
import com.apitable.shared.constants.NotificationConstants;
import com.apitable.shared.context.LoginContext;
import com.apitable.shared.security.PasswordService;
import com.apitable.shared.sysconfig.notification.NotificationTemplate;
-import com.apitable.shared.util.RandomExtendUtil;
import com.apitable.space.entity.SpaceEntity;
import com.apitable.space.mapper.SpaceMapper;
import com.apitable.space.ro.SpaceUpdateOpRo;
@@ -100,12 +97,12 @@ import com.apitable.user.service.IUserService;
import com.apitable.user.vo.UserInfoVo;
import com.apitable.user.vo.UserLinkVo;
import com.apitable.workspace.service.INodeShareService;
-import com.apitable.core.exception.BusinessException;
-import com.apitable.core.util.ExceptionUtil;
-import com.apitable.core.util.HttpContextUtil;
-import com.apitable.core.util.SqlTool;
-
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
@@ -129,148 +126,237 @@ import static com.apitable.user.enums.UserException.USER_LANGUAGE_SET_UN_SUPPORT
import static com.apitable.user.enums.UserException.USER_NOT_EXIST;
import static com.apitable.user.enums.UserOperationType.COMPLETE_CLOSING;
-/**
- *
- * User table service implementation class
- *
- */
+/** User table service implementation class. */
@Service
@Slf4j
-public class UserServiceImpl extends ServiceImpl implements IUserService {
+public class UserServiceImpl extends ServiceImpl
+ implements IUserService {
+
+ /** */
+ private static final int USER_AVATAR_COLOR_MAX_VALUE = 10;
+ /** */
+ private static final int USER_IS_PAUSED_CLOSE_DAY = 30;
+
+ /** */
private static final int QUERY_LOCALE_IN_EMAILS_LIMIT = 200;
+ /** */
@Resource
private LoginUserCacheService loginUserCacheService;
+ /** */
@Resource
private IAssetService iAssetService;
+ /** */
@Resource
private ISpaceService iSpaceService;
+ /** */
@Resource
private IPlayerActivityService iPlayerActivityService;
+ /** */
@Resource
private UserActiveSpaceCacheService userActiveSpaceCacheService;
+ /** */
@Resource
private UserSpaceCacheService userSpaceCacheService;
+ /** */
@Resource
private UserSpaceOpenedSheetCacheService userSpaceOpenedSheetCacheService;
+ /** */
@Resource
private INodeShareService nodeShareService;
+ /** */
@Resource
private ISpaceInviteLinkService spaceInviteLinkService;
+ /** */
@Resource
private IPlayerNotificationService notificationService;
+ /** */
@Resource
private MemberMapper memberMapper;
+ /** */
@Resource
private SpaceMapper spaceMapper;
- @Resource
- private ConstProperties constProperties;
-
+ /** */
@Resource
private FindByIndexNameSessionRepository extends Session> sessions;
+ /** */
@Resource
private IUserHistoryService iUserHistoryService;
+ /** */
@Resource
private UserMapper userMapper;
+ /** */
@Resource
private SocialServiceFacade socialServiceFacade;
+ /** */
@Resource
private IMemberService iMemberService;
+ /** */
@Resource
private INotificationFactory notificationFactory;
+ /** */
@Resource
private UserServiceFacade userServiceFacade;
+ /** */
@Resource
private UserLinkServiceFacade userLinkServiceFacade;
+ /** */
@Resource
private PasswordService passwordService;
+ /** */
@Resource
private IDeveloperService iDeveloperService;
+ /**
+ * *
+ * @param mobile cell-phone number
+ * @return user id
+ */
@Override
- public Long getUserIdByMobile(String mobile) {
+ public Long getUserIdByMobile(final String mobile) {
return baseMapper.selectIdByMobile(mobile);
}
+ /**
+ * *
+ * @param email email
+ * @return user id
+ */
@Override
- public Long getUserIdByEmail(String email) {
+ public Long getUserIdByEmail(final String email) {
return baseMapper.selectIdByEmail(email);
}
+ /**
+ * *
+ * @param code Area code
+ * @param mobile Phone number
+ * @return boolean
+ */
@Override
- public boolean checkByCodeAndMobile(String code, String mobile) {
- code = StrUtil.prependIfMissing(code, "+");
+ public boolean checkByCodeAndMobile(final String code,
+ final String mobile) {
+ String areaCode = StrUtil.prependIfMissing(code, "+");
UserEntity userEntity = baseMapper.selectByMobile(mobile);
if (userEntity == null) {
return false;
}
- return StrUtil.isNotBlank(userEntity.getCode()) && userEntity.getCode().equals(code);
+ return StrUtil.isNotBlank(userEntity.getCode())
+ && userEntity.getCode().equals(areaCode);
}
+ /**
+ * *
+ * @param email email
+ * @return boolean
+ */
@Override
- public boolean checkByEmail(String email) {
+ public boolean checkByEmail(final String email) {
return SqlTool.retCount(baseMapper.selectCountByEmail(email)) > 0;
}
+ /**
+ * *
+ * @param code Area code
+ * @param mobilePhone Phone number
+ * @return UserEntity
+ */
@Override
- public UserEntity getByCodeAndMobilePhone(String code, String mobilePhone) {
- code = StrUtil.prependIfMissing(code, "+");
+ public UserEntity getByCodeAndMobilePhone(final String code,
+ final String mobilePhone) {
+ String areaCode = StrUtil.prependIfMissing(code, "+");
UserEntity userEntity = baseMapper.selectByMobile(mobilePhone);
if (userEntity == null) {
return null;
}
- if (StrUtil.isNotBlank(userEntity.getCode()) && userEntity.getCode().equals(code)) {
+ if (StrUtil.isNotBlank(userEntity.getCode())
+ && userEntity.getCode().equals(areaCode)) {
return userEntity;
}
return null;
}
+ /**
+ * *
+ * @param code Area code
+ * @param mobilePhones Mobile number list
+ * @return List
+ */
@Override
- public List getByCodeAndMobilePhones(String code, Collection mobilePhones) {
- List userEntities = baseMapper.selectByMobilePhoneIn(mobilePhones);
+ public List getByCodeAndMobilePhones(
+ final String code, final Collection mobilePhones) {
+ List userEntities =
+ baseMapper.selectByMobilePhoneIn(mobilePhones);
if (userEntities.isEmpty()) {
return userEntities;
}
String finalCode = StrUtil.prependIfMissing(code, "+");
- return userEntities.stream().filter(user -> StrUtil.isNotBlank(user.getCode()) && user.getCode().equals(finalCode))
- .collect(Collectors.toList());
+ return userEntities.stream()
+ .filter(user -> StrUtil.isNotBlank(user.getCode())
+ && user.getCode().equals(finalCode))
+ .collect(Collectors.toList());
}
+ /**
+ * *
+ * @param email email
+ * @return UserEntity
+ */
@Override
- public UserEntity getByEmail(String email) {
+ public UserEntity getByEmail(final String email) {
return baseMapper.selectByEmail(email);
}
+ /**
+ * *
+ * @param emails email list
+ * @return List
+ */
@Override
- public List getByEmails(Collection emails) {
+ public List getByEmails(final Collection emails) {
return baseMapper.selectByEmails(emails);
}
+ /**
+ * *
+ * @param externalId External System ID
+ * @param nickName Nickname
+ * @param avatar Avatar
+ * @param email email
+ * @param remark Remarks
+ * @return user id
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public Long createByExternalSystem(String externalId, String nickName, String avatar, String email, String remark) {
+ public Long createByExternalSystem(
+ final String externalId,
+ final String nickName,
+ final String avatar,
+ final String email,
+ final String remark
+ ) {
if (StrUtil.isNotBlank(email)) {
// Query whether the existing mail exists
UserEntity selectUser = baseMapper.selectByEmail(email);
@@ -285,16 +371,21 @@ public class UserServiceImpl extends ServiceImpl impleme
if (!flag) {
throw new BusinessException(SIGN_IN_ERROR);
}
- socialServiceFacade.createSocialUser(new SocialUserBind(selectUser.getId(), externalId));
+ socialServiceFacade.createSocialUser(
+ new SocialUserBind(selectUser.getId(), externalId));
return selectUser.getId();
}
}
log.info("Create Account");
UserEntity user = new UserEntity();
user.setUuid(IdUtil.fastSimpleUUID());
- user.setNickName(StrUtil.isNotBlank(nickName) ? nickName : StringUtils.substringBefore(email, "@"));
+ String name = StrUtil.isNotBlank(nickName) ? nickName
+ : StringUtils.substringBefore(email, "@");
+ user.setNickName(name);
user.setAvatar(StrUtil.isNotBlank(avatar) ? avatar : null);
- user.setColor(StrUtil.isNotBlank(avatar) ? null : RandomUtil.randomInt(1, 12));
+ Integer color = StrUtil.isNotBlank(avatar) ? null
+ : RandomUtil.randomInt(0, USER_AVATAR_COLOR_MAX_VALUE);
+ user.setColor(color);
user.setEmail(email);
user.setLastLoginTime(LocalDateTime.now());
user.setRemark(remark);
@@ -303,13 +394,16 @@ public class UserServiceImpl extends ServiceImpl impleme
throw new BusinessException(SIGN_IN_ERROR);
}
if (StrUtil.isNotBlank(email)) {
- // If the mail has been invited and has not been bound to other accounts, activate the space members of the invited mail
- List inactiveMembers = iMemberService.getInactiveMemberByEmails(email);
+ // If the mail has been invited
+ // and has not been bound to other accounts,
+ // activate the space members of the invited mail
+ List inactiveMembers =
+ iMemberService.getInactiveMemberByEmails(email);
inactiveMemberProcess(user.getId(), inactiveMembers);
- }
- else {
+ } else {
String spaceName = user.getNickName();
- if (LocaleContextHolder.getLocale().equals(LanguageManager.me().getDefaultLanguage())) {
+ if (LocaleContextHolder.getLocale()
+ .equals(LanguageManager.me().getDefaultLanguage())) {
spaceName += SPACE_NAME_DEFAULT_SUFFIX;
}
iSpaceService.createSpace(user, spaceName);
@@ -319,44 +413,76 @@ public class UserServiceImpl extends ServiceImpl impleme
// Create personal invitation code
userServiceFacade.createInvitationCode(user.getId());
// Create Associated User
- socialServiceFacade.createSocialUser(new SocialUserBind(user.getId(), externalId));
+ socialServiceFacade.createSocialUser(
+ new SocialUserBind(user.getId(), externalId));
return user.getId();
}
+ /**
+ * *
+ * @param user user entity
+ * @return boolean
+ */
@Override
- public boolean saveUser(UserEntity user) {
+ public boolean saveUser(final UserEntity user) {
boolean flag = save(user);
TaskManager.me().execute(() -> {
// jump to third site
NotificationTemplate template =
- notificationFactory.getTemplateById(NotificationTemplateId.NEW_USER_WELCOME_NOTIFY.getValue());
+ notificationFactory.getTemplateById(NotificationTemplateId
+ .NEW_USER_WELCOME_NOTIFY.getValue());
Dict extras = Dict.create();
- if (StrUtil.isNotBlank(template.getUrl()) && template.getUrl().startsWith("http")) {
+ if (StrUtil.isNotBlank(template.getUrl())
+ && template.getUrl().startsWith("http")) {
Dict toast = Dict.create();
toast.put(EXTRA_TOAST_URL, template.getUrl());
- toast.put("onClose", ListUtil.toList("mark_cur_notice_to_read()"));
- toast.put("onBtnClick", ListUtil.toList("window_open_url()"));
+ toast.put("onClose",
+ ListUtil.toList("mark_cur_notice_to_read()"));
+ toast.put("onBtnClick",
+ ListUtil.toList("window_open_url()"));
toast.put("duration", 0);
toast.put("closable", true);
extras.put(EXTRA_TOAST, toast);
}
- NotificationManager.me().playerNotify(NotificationTemplateId.NEW_USER_WELCOME_NOTIFY,
+ NotificationManager.me()
+ .playerNotify(NotificationTemplateId.NEW_USER_WELCOME_NOTIFY,
Collections.singletonList(user.getId()), 0L, null, extras);
});
return flag;
}
+ /**
+ * *
+ * @param areaCode Area code
+ * @param mobile Phone number
+ * @param nickName Third party user nickname
+ * @param avatar Third party user avatar
+ * @param email email
+ * @param spaceName Name of the new space
+ * @return user id
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public Long create(String areaCode, String mobile, String nickName, String avatar, String email, String spaceName) {
+ public Long create(
+ final String areaCode,
+ final String mobile,
+ final String nickName,
+ final String avatar,
+ final String email,
+ final String spaceName
+ ) {
+ Integer color = nullToDefaultAvatar(avatar) != null ? null
+ : RandomUtil.randomInt(0, USER_AVATAR_COLOR_MAX_VALUE);
+ String name = nullToDefaultNickName(nickName, mobile != null
+ ? mobile : StringUtils.substringBefore(email, "@"));
// Create user with mobile number
UserEntity entity = UserEntity.builder()
.uuid(IdUtil.fastSimpleUUID())
.code(areaCode)
.mobilePhone(mobile)
- .nickName(nullToDefaultNickName(nickName, mobile != null ? mobile : StringUtils.substringBefore(email, "@")))
+ .nickName(name)
.avatar(nullToDefaultAvatar(avatar))
- .color(nullToDefaultAvatar(avatar) != null ? null : RandomUtil.randomInt(1,12))
+ .color(color)
.email(email)
.lastLoginTime(LocalDateTime.now())
.build();
@@ -364,13 +490,18 @@ public class UserServiceImpl extends ServiceImpl impleme
ExceptionUtil.isTrue(flag, REGISTER_FAIL);
boolean hasSpace = false;
if (email != null) {
- // If the mailbox has been invited and has not been bound to other accounts, activate the space members of the invited mailbox
- List inactiveMembers = iMemberService.getInactiveMemberByEmails(email);
- hasSpace = this.inactiveMemberProcess(entity.getId(), inactiveMembers);
+ // If the mailbox has been invited
+ // and has not been bound to other accounts,
+ // activate the space members of the invited mailbox
+ List inactiveMembers =
+ iMemberService.getInactiveMemberByEmails(email);
+ hasSpace = this.inactiveMemberProcess(entity.getId(),
+ inactiveMembers);
}
// Activate imported members
if (mobile != null) {
- int count = memberMapper.updateUserIdByMobile(entity.getId(), mobile);
+ int count =
+ memberMapper.updateUserIdByMobile(entity.getId(), mobile);
hasSpace = hasSpace || count > 0;
}
// No space to create a space automatically
@@ -378,10 +509,10 @@ public class UserServiceImpl extends ServiceImpl impleme
String newSpaceName;
if (StrUtil.isNotBlank(spaceName)) {
newSpaceName = spaceName;
- }
- else {
+ } else {
newSpaceName = entity.getNickName();
- if (LocaleContextHolder.getLocale().equals(LanguageManager.me().getDefaultLanguage())) {
+ if (LocaleContextHolder.getLocale()
+ .equals(LanguageManager.me().getDefaultLanguage())) {
newSpaceName += SPACE_NAME_DEFAULT_SUFFIX;
}
}
@@ -394,18 +525,33 @@ public class UserServiceImpl extends ServiceImpl impleme
return entity.getId();
}
+ /**
+ * *
+ * @param areaCode Area code
+ * @param mobile Phone number
+ * @param nickName Third party user nickname
+ * @param avatar Third party user avatar
+ * @return UserEntity
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public UserEntity createUserByMobilePhone(String areaCode, String mobile, String nickName, String avatar) {
+ public UserEntity createUserByMobilePhone(
+ final String areaCode,
+ final String mobile,
+ final String nickName,
+ final String avatar
+ ) {
+ Integer color = nullToDefaultAvatar(avatar) != null ? null
+ : RandomUtil.randomInt(0, USER_AVATAR_COLOR_MAX_VALUE);
UserEntity entity = UserEntity.builder()
- .uuid(IdUtil.fastSimpleUUID())
- .code(areaCode)
- .mobilePhone(mobile)
- .nickName(nullToDefaultNickName(nickName, mobile))
- .avatar(nullToDefaultAvatar(avatar))
- .color(nullToDefaultAvatar(avatar) != null ? null : RandomUtil.randomInt(1,12))
- .lastLoginTime(LocalDateTime.now())
- .build();
+ .uuid(IdUtil.fastSimpleUUID())
+ .code(areaCode)
+ .mobilePhone(mobile)
+ .nickName(nullToDefaultNickName(nickName, mobile))
+ .avatar(nullToDefaultAvatar(avatar))
+ .color(color)
+ .lastLoginTime(LocalDateTime.now())
+ .build();
boolean flag = saveUser(entity);
ExceptionUtil.isTrue(flag, REGISTER_FAIL);
// Create user activity record
@@ -415,16 +561,21 @@ public class UserServiceImpl extends ServiceImpl impleme
return entity;
}
+ /**
+ * *
+ * @param email email
+ * @return UserEntity
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public UserEntity createUserByEmail(String email) {
+ public UserEntity createUserByEmail(final String email) {
UserEntity entity = UserEntity.builder()
- .uuid(IdUtil.fastSimpleUUID())
- .email(email)
- .nickName(StringUtils.substringBefore(email, "@"))
- .color(RandomUtil.randomInt(1, 12))
- .lastLoginTime(LocalDateTime.now())
- .build();
+ .uuid(IdUtil.fastSimpleUUID())
+ .email(email)
+ .nickName(StringUtils.substringBefore(email, "@"))
+ .color(RandomUtil.randomInt(0, USER_AVATAR_COLOR_MAX_VALUE))
+ .lastLoginTime(LocalDateTime.now())
+ .build();
boolean flag = saveUser(entity);
ExceptionUtil.isTrue(flag, REGISTER_FAIL);
// Create user activity record
@@ -434,45 +585,69 @@ public class UserServiceImpl extends ServiceImpl impleme
return entity;
}
-
+ /**
+ * *
+ * @param user user entity
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void initialDefaultSpaceForUser(UserEntity user) {
+ public void initialDefaultSpaceForUser(final UserEntity user) {
// initial default space for new come user
String spaceName = user.getNickName();
- if (LocaleContextHolder.getLocale().equals(LanguageManager.me().getDefaultLanguage())) {
+ if (LocaleContextHolder.getLocale()
+ .equals(LanguageManager.me().getDefaultLanguage())) {
spaceName += SPACE_NAME_DEFAULT_SUFFIX;
}
iSpaceService.createSpace(user, spaceName);
}
+ /**
+ * *
+ * @param userId User ID
+ * @return boolean
+ */
@Override
- public boolean checkUserHasBindEmail(Long userId) {
+ public boolean checkUserHasBindEmail(final Long userId) {
log.info("Query whether users bind email");
UserEntity user = getById(userId);
ExceptionUtil.isNotNull(user, USER_NOT_EXIST);
return user.getEmail() != null;
}
+ /**
+ * *
+ * @param userId User ID
+ * @param spaceId Space ID
+ * @param email email
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void bindMemberByEmail(Long userId, String spaceId, String email) {
+ public void bindMemberByEmail(final Long userId, final String spaceId,
+ final String email) {
log.info("Bind member email");
// Determine whether the email is unbound and invited
- MemberEntity member = iMemberService.getBySpaceIdAndEmail(spaceId, email);
+ MemberEntity member =
+ iMemberService.getBySpaceIdAndEmail(spaceId, email);
ExceptionUtil.isNotNull(member, INVITE_EMAIL_NOT_EXIT);
ExceptionUtil.isNull(member.getUserId(), INVITE_EMAIL_HAS_LINK);
- // Judge whether the requesting user's mailbox is bound to another email, and the user's email must be empty
+ // Judge whether the requesting user's mailbox is bound
+ // to another email, and the user's email must be empty
String userEmail = baseMapper.selectEmailById(userId);
ExceptionUtil.isBlank(userEmail, LINK_EMAIL_ERROR);
- // Bind as user email, and the email will be activated by invited space members together
+ // Bind as user email, and the email
+ // will be activated by invited space members together
updateEmailByUserId(userId, email);
}
+ /**
+ * *
+ * @param userId User ID
+ * @param email email
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void updateEmailByUserId(Long userId, String email) {
+ public void updateEmailByUserId(final Long userId, final String email) {
log.info("Modify User [{}] email [{}]", userId, email);
UserEntity updateUser = new UserEntity();
updateUser.setId(userId);
@@ -481,20 +656,29 @@ public class UserServiceImpl extends ServiceImpl impleme
ExceptionUtil.isTrue(flag, LINK_EMAIL_ERROR);
// Synchronize member information email
iMemberService.updateEmailByUserId(userId, email);
- // If the email has been invited and has not been bound to other accounts, activate the space members of the invited email
- List inactiveMembers = iMemberService.getInactiveMemberByEmails(email);
+ // If the email has been invited
+ // and has not been bound to other accounts,
+ // activate the space members of the invited email
+ List inactiveMembers =
+ iMemberService.getInactiveMemberByEmails(email);
this.inactiveMemberProcess(userId, inactiveMembers);
// Delete Cache
loginUserCacheService.delete(userId);
}
+ /**
+ * *
+ * @param userId User ID
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void unbindEmailByUserId(Long userId) {
- // The user needs to bind at least one contact (mobile phone number, email) to unbind the email
+ public void unbindEmailByUserId(final Long userId) {
+ // The user needs to bind at least
+ // one contact (mobile phone number, email) to unbind the email
LoginUserDto userDto = loginUserCacheService.getLoginUser(userId);
ExceptionUtil.isNotBlank(userDto.getMobile(), MUST_BIND_MOBILE);
- boolean flag = SqlHelper.retBool(baseMapper.resetEmailByUserId(userId));
+ boolean flag =
+ SqlHelper.retBool(baseMapper.resetEmailByUserId(userId));
ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR);
// Synchronize unbound member information email
iMemberService.resetEmailByUserId(userId);
@@ -502,9 +686,16 @@ public class UserServiceImpl extends ServiceImpl impleme
loginUserCacheService.delete(userId);
}
+ /**
+ * *
+ * @param userId User ID
+ * @param code Area code
+ * @param mobile Phone number
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void updateMobileByUserId(Long userId, String code, String mobile) {
+ public void updateMobileByUserId(final Long userId, final String code,
+ final String mobile) {
LoginUserDto userDto = loginUserCacheService.getLoginUser(userId);
UserEntity updateUser = new UserEntity();
updateUser.setId(userId);
@@ -514,27 +705,37 @@ public class UserServiceImpl extends ServiceImpl impleme
ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR);
// Synchronize the mobile number of member information
iMemberService.updateMobileByUserId(userId, mobile);
- // If the mobile phone number has been invited and no other account has been bound, activate the invited space member
- List inactiveMembers = iMemberService.getInactiveMemberByEmails(mobile);
+ // If the mobile phone number has been invited
+ // and no other account has been bound,
+ // activate the invited space member
+ List inactiveMembers =
+ iMemberService.getInactiveMemberByEmails(mobile);
this.inactiveMemberProcess(userId, inactiveMembers);
// Delete Cache
loginUserCacheService.delete(userId);
- // Email registration is bound to mobile phones for the first time, and additional invitation rewards are given
+ // Email registration is bound to mobile phones for the first time,
+ // and additional invitation rewards are given
if (userDto.getMobile() == null) {
- TaskManager.me().execute(() -> {
- userServiceFacade.rewardUserInfoUpdateAction(new RewardedUser(userId, userDto.getNickName()));
- });
+ TaskManager.me() .execute(
+ () -> userServiceFacade.rewardUserInfoUpdateAction(
+ new RewardedUser(userId, userDto.getNickName())));
}
}
+ /**
+ * *
+ * @param userId User Id
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void unbindMobileByUserId(Long userId) {
- // The user needs to bind at least one contact (phone number, email) to unbind the mobile phone number
+ public void unbindMobileByUserId(final Long userId) {
+ // The user needs to bind at least one contact (phone number, email)
+ // to unbind the mobile phone number
LoginUserDto userDto = loginUserCacheService.getLoginUser(userId);
ExceptionUtil.isNotBlank(userDto.getEmail(), MUST_BIND_EAMIL);
- boolean flag = SqlHelper.retBool(baseMapper.resetMobileByUserId(userId));
+ boolean flag =
+ SqlHelper.retBool(baseMapper.resetMobileByUserId(userId));
ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR);
// Synchronize the mobile phone number of unbinding member information
iMemberService.resetMobileByUserId(userId);
@@ -542,8 +743,12 @@ public class UserServiceImpl extends ServiceImpl impleme
loginUserCacheService.delete(userId);
}
+ /**
+ * *
+ * @param userId User ID
+ */
@Override
- public void updateLoginTime(Long userId) {
+ public void updateLoginTime(final Long userId) {
// Update the last login time
UserEntity update = new UserEntity();
update.setId(userId);
@@ -552,45 +757,62 @@ public class UserServiceImpl extends ServiceImpl impleme
ExceptionUtil.isTrue(flag, SIGN_IN_ERROR);
}
+ /**
+ * *
+ * @param userId User ID
+ * @param param Operate parameters
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void edit(Long userId, UserOpRo param) {
+ public void edit(final Long userId, final UserOpRo param) {
log.info("Edit user information");
UserEntity userEntity = getById(userId);
ExceptionUtil.isNotNull(userEntity, USER_NOT_EXIST);
UserEntity user = UserEntity.builder().id(userId).build();
- String waitDeleteOldAvatar = userEntity.getAvatar();
+ String waitDeleteOldAvatar = null;
if (StrUtil.isNotBlank(param.getAvatar())) {
- user.setAvatar(param.getAvatar());
- user.setColor(null);
+ waitDeleteOldAvatar = userEntity.getAvatar();
+ userMapper.updateUserAvatarInfo(userId, param.getAvatar(), null);
}
- else {
- user.setAvatar(null);
- user.setColor(param.getAvatarColor());
+ if (ObjectUtil.isNotNull(param.getAvatarColor())) {
+ userMapper.updateUserAvatarInfo(userId, null,
+ param.getAvatarColor());
}
if (StrUtil.isNotBlank(param.getLocale())) {
- ExceptionUtil.isTrue(LanguageConstants.isLanguagesSupported(param.getLocale()), USER_LANGUAGE_SET_UN_SUPPORTED);
+ ExceptionUtil.isTrue(
+ LanguageConstants.isLanguagesSupported(param.getLocale()),
+ USER_LANGUAGE_SET_UN_SUPPORTED);
user.setLocale(param.getLocale());
}
if (StrUtil.isNotBlank(param.getNickName())) {
- // Initialize the nickname. If there is a space "space of *** planet residents" registered and automatically created, synchronously modify the space name
+ // Initialize the nickname.
+ // If there is a space "space of *** planet residents" registered
+ // and automatically created, synchronously modify the space name
if (BooleanUtil.isTrue(param.getInit())) {
- String spaceId = spaceMapper.selectSpaceIdByUserIdAndName(userId, userEntity.getNickName());
+ String spaceId =
+ spaceMapper.selectSpaceIdByUserIdAndName(userId,
+ userEntity.getNickName());
if (StrUtil.isNotBlank(spaceId)) {
String spaceName = param.getNickName();
- if (LocaleContextHolder.getLocale().equals(LanguageManager.me().getDefaultLanguage())) {
+ if (LocaleContextHolder.getLocale()
+ .equals(LanguageManager.me().getDefaultLanguage())) {
spaceName += SPACE_NAME_DEFAULT_SUFFIX;
}
- iSpaceService.updateSpace(userId, spaceId, SpaceUpdateOpRo.builder().name(spaceName).build());
+ iSpaceService.updateSpace(userId, spaceId,
+ SpaceUpdateOpRo.builder().name(spaceName).build());
}
}
- // Synchronize personal nickname to member name that has not been modified
- iMemberService.updateMemberNameByUserId(userId, param.getNickName());
+ // Synchronize personal nickname to
+ // member name that has not been modifie
+ iMemberService.updateMemberNameByUserId(userId,
+ param.getNickName());
// Synchronously modify member 'Social Name Modified' field status
memberMapper.updateSocialNameModifiedByUserId(userId);
// Delete the space cache with modified member names
TaskManager.me().execute(() -> {
- List spaceIds = iMemberService.getSpaceIdWithoutNameModifiedByUserId(userId);
+ List spaceIds =
+ iMemberService.getSpaceIdWithoutNameModifiedByUserId(
+ userId);
for (String spcId : spaceIds) {
userSpaceCacheService.delete(userId, spcId);
}
@@ -598,22 +820,31 @@ public class UserServiceImpl extends ServiceImpl impleme
user.setNickName(param.getNickName())
.setIsSocialNameModified(SocialNameModified.YES.getValue());
if (BooleanUtil.isTrue(param.getInit())) {
- userServiceFacade.onUserChangeNicknameAction(userId, param.getNickName());
+ userServiceFacade.onUserChangeNicknameAction(userId,
+ param.getNickName());
}
+ } else {
+ user.setNickName(userEntity.getNickName());
}
boolean flag = updateById(user);
ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR);
// Delete Cache
loginUserCacheService.delete(userId);
- if (StrUtil.isNotBlank(waitDeleteOldAvatar) && StrUtil.startWith(waitDeleteOldAvatar, PUBLIC_PREFIX)) {
+ if (StrUtil.isNotBlank(waitDeleteOldAvatar)
+ && StrUtil.startWith(waitDeleteOldAvatar, PUBLIC_PREFIX)) {
// Delete original cloud files
iAssetService.delete(waitDeleteOldAvatar);
}
}
+ /**
+ * *
+ * @param id user id
+ * @param password New password set
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void updatePwd(Long id, String password) {
+ public void updatePwd(final Long id, final String password) {
log.info("Change Password");
UserEntity user = UserEntity.builder()
.id(id)
@@ -626,64 +857,87 @@ public class UserServiceImpl extends ServiceImpl impleme
ExceptionUtil.isTrue(flag, MODIFY_PASSWORD_ERROR);
}
+ /**
+ * *
+ * @param userId User ID
+ * @param spaceId Space ID
+ * @param filter Whether to filter space related information
+ * @return UserInfoVo
+ */
@Override
- public UserInfoVo getCurrentUserInfo(Long userId, String spaceId, Boolean filter) {
+ public UserInfoVo getCurrentUserInfo(final Long userId,
+ final String spaceId, final Boolean filter) {
log.info("Get user information and space content");
// Query the user's basic information
// Whether the invitation code has been used for rewards
- boolean usedInviteReward = userServiceFacade.getInvitationReward(userId);
- UserInfoVo userInfo = UserInfoVo.builder().sendSubscriptionNotify(true)
- .usedInviteReward(usedInviteReward)
- .build();
+ boolean usedInviteReward =
+ userServiceFacade.getInvitationReward(userId);
+ UserInfoVo userInfo = UserInfoVo.builder()
+ .sendSubscriptionNotify(true)
+ .usedInviteReward(usedInviteReward)
+ .build();
LoginUserDto loginUserDto = LoginContext.me().getLoginUser();
userInfo.transferDataFromLoginUserDto(loginUserDto);
- UserLinkInfo userLinkInfo = userLinkServiceFacade.getUserLinkInfo(userId);
+ UserLinkInfo userLinkInfo =
+ userLinkServiceFacade.getUserLinkInfo(userId);
if (userLinkInfo != null) {
// Copy third-party account associated information
- List userLinkVos = new ArrayList<>(userLinkInfo.getAccountLinkList().size());
+ List userLinkVos =
+ new ArrayList<>(userLinkInfo.getAccountLinkList().size());
for (int i = 0; i < userLinkInfo.getAccountLinkList().size(); i++) {
UserLinkVo linkVo = new UserLinkVo();
- BeanUtil.copyProperties(userLinkInfo.getAccountLinkList().get(i), linkVo);
+ BeanUtil.copyProperties(
+ userLinkInfo.getAccountLinkList().get(i), linkVo);
userLinkVos.add(linkVo);
}
userInfo.transferDataFromDto(userLinkInfo, userLinkVos);
- }
- else {
+ } else {
userInfo.setApiKey(iDeveloperService.getApiKeyByUserId(userId));
}
- if (userInfo.getIsPaused()) { // Cancel the account during the calm period, and calculate the official cancellation time
- UserHistoryEntity userHistory = iUserHistoryService
- .getLatestUserHistoryEntity(userId, UserOperationType.APPLY_FOR_CLOSING);
- ExceptionUtil.isNotNull(userHistory, UserClosingException.USER_HISTORY_RECORD_ISSUE);
- userInfo.setCloseAt(userHistory.getCreatedAt().plusDays(30).withHour(0).withMinute(0).withSecond(0));
+ // Cancel the account during the calm period,
+ // and calculate the official cancellation time
+ if (userInfo.getIsPaused()) {
+ UserHistoryEntity userHistory =
+ iUserHistoryService.getLatestUserHistoryEntity(userId,
+ UserOperationType.APPLY_FOR_CLOSING);
+ ExceptionUtil.isNotNull(userHistory,
+ UserClosingException.USER_HISTORY_RECORD_ISSUE);
+ userInfo.setCloseAt(userHistory.getCreatedAt()
+ .plusDays(USER_IS_PAUSED_CLOSE_DAY)
+ .withHour(0)
+ .withMinute(0)
+ .withSecond(0));
}
boolean noSpace = StrUtil.isBlank(spaceId);
+ String spcId = spaceId;
// Selectively filter spatial related information
if (BooleanUtil.isTrue(filter)) {
if (noSpace) {
return userInfo;
}
- Long memberId = iMemberService.getMemberIdByUserIdAndSpaceId(userId, spaceId);
+ Long memberId =
+ iMemberService.getMemberIdByUserIdAndSpaceId(userId, spcId);
if (ObjectUtil.isNull(memberId)) {
return userInfo;
}
- }
- else if (noSpace) {
- // When the space ID is not transferred, obtain the space ID of the user's recent work
- String activeSpaceId = userActiveSpaceCacheService.getLastActiveSpace(userId);
+ } else if (noSpace) {
+ // When the space ID is not transferred,
+ // obtain the space ID of the user's recent work
+ String activeSpaceId =
+ userActiveSpaceCacheService.getLastActiveSpace(userId);
if (StrUtil.isBlank(activeSpaceId)) {
return userInfo;
}
- spaceId = activeSpaceId;
- }
- else {
+ spcId = activeSpaceId;
+ } else {
// Prevent access to not join spaces
- userSpaceCacheService.getMemberId(userId, spaceId);
+ userSpaceCacheService.getMemberId(userId, spcId);
}
userInfo.setNeedCreate(false);
// Cache session
- UserSpaceDto userSpace = userSpaceCacheService.getUserSpace(userId, spaceId);
+ UserSpaceDto userSpace =
+ userSpaceCacheService.getUserSpace(userId, spcId);
userInfo.setSpaceId(userSpace.getSpaceId());
userInfo.setSpaceName(userSpace.getSpaceName());
userInfo.setSpaceLogo(userSpace.getSpaceLogo());
@@ -693,12 +947,15 @@ public class UserServiceImpl extends ServiceImpl impleme
userInfo.setIsAdmin(userSpace.isAdmin() || userSpace.isMainAdmin());
userInfo.setIsMainAdmin(userSpace.isMainAdmin());
userInfo.setIsDelSpace(userSpace.isDel());
- userInfo.setIsNewComer(!iMemberService.checkUserHasModifyNameInSpace(userId));
+ userInfo.setIsNewComer(
+ !iMemberService.checkUserHasModifyNameInSpace(userId));
userInfo.setIsMemberNameModified(userSpace.getIsMemberNameModified());
// Get the last opened data table information
- OpenedSheet openedSheet = userSpaceOpenedSheetCacheService.getOpenedSheet(userId, spaceId);
- if (ObjectUtil.isNotNull(openedSheet) && ObjectUtil.isNotNull(openedSheet.getNodeId())) {
+ OpenedSheet openedSheet =
+ userSpaceOpenedSheetCacheService.getOpenedSheet(userId, spcId);
+ if (ObjectUtil.isNotNull(openedSheet)
+ && ObjectUtil.isNotNull(openedSheet.getNodeId())) {
userInfo.setActiveNodeId(openedSheet.getNodeId());
userInfo.setActiveViewId(openedSheet.getViewId());
userInfo.setActiveNodePos(openedSheet.getPosition());
@@ -707,11 +964,18 @@ public class UserServiceImpl extends ServiceImpl impleme
return userInfo;
}
+ /**
+ * *
+ * @param userId User ID
+ * @param isRetain Whether to keep the current session
+ */
@Override
- public void closeMultiSession(Long userId, boolean isRetain) {
- Collection extends Session> usersSessions = this.sessions.findByPrincipalName(userId.toString()).values();
+ public void closeMultiSession(final Long userId, final boolean isRetain) {
+ Collection extends Session> usersSessions =
+ this.sessions.findByPrincipalName(userId.toString()).values();
if (CollUtil.isNotEmpty(usersSessions)) {
- List idList = usersSessions.stream().map(Session::getId).collect(Collectors.toList());
+ List idList = usersSessions.stream()
+ .map(Session::getId).collect(Collectors.toList());
if (isRetain) {
HttpSession httpSession = HttpContextUtil.getSession(false);
if (httpSession != null) {
@@ -724,19 +988,33 @@ public class UserServiceImpl extends ServiceImpl impleme
}
}
+ /**
+ * *
+ * @param userId User ID
+ * @return uuid
+ */
@Override
- public String getUuidByUserId(Long userId) {
+ public String getUuidByUserId(final Long userId) {
return baseMapper.selectUuidById(userId);
}
+ /**
+ * *
+ * @param userId user id
+ * @return Nickname
+ */
@Override
- public String getNicknameByUserId(Long userId) {
+ public String getNicknameByUserId(final Long userId) {
return baseMapper.selectNickNameById(userId);
}
+ /**
+ * *
+ * @param user User
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void applyForClosingAccount(UserEntity user) {
+ public void applyForClosingAccount(final UserEntity user) {
// Update the user logoff cool down period status to Yes
updateIsPaused(user.getId(), true);
// Add User Operation Record
@@ -751,29 +1029,35 @@ public class UserServiceImpl extends ServiceImpl impleme
if (members.size() == 0) {
return;
}
- List memberIds = members.stream().map(MemberEntity::getId).collect(Collectors.toList());
+ List memberIds = members.stream()
+ .map(MemberEntity::getId).collect(Collectors.toList());
spaceInviteLinkService.deleteByMemberIds(memberIds);
// Logical delete member information
iMemberService.preDelByMemberIds(memberIds);
- // notify the main admin about this member is going to close his account.
- List spaceIds = members.stream().map(MemberEntity::getSpaceId).collect(Collectors.toList());
+ // notify the main admin about
+ // this member is going to close his account.
+ List spaceIds = members.stream()
+ .map(MemberEntity::getSpaceId).collect(Collectors.toList());
List spaces = iSpaceService.getBySpaceIds(spaceIds);
if (spaces.size() == 0) {
return;
}
- List notificationCreateRos = genNotificationCreateRos(user, spaces);
+ List notificationCreateRos =
+ genNotificationCreateRos(user, spaces);
notificationService.batchCreateNotify(notificationCreateRos);
}
/**
- * Encapsulate Notification to notify the master administrator that the member has applied for logoff
+ * Encapsulate Notification to notify the master administrator
+ * * that the member has applied for logoff.
*
- * @param user User
+ * @param user User
* @param spaces Space List
* @return NotificationCreateRo List
*/
- private List genNotificationCreateRos(UserEntity user, List spaces) {
+ private List genNotificationCreateRos(
+ final UserEntity user, final List spaces) {
List ros = Lists.newArrayList();
spaces.forEach(spaceEntity -> {
NotificationCreateRo notifyRo = new NotificationCreateRo();
@@ -782,30 +1066,38 @@ public class UserServiceImpl extends ServiceImpl impleme
notifyRo.setToMemberId(Lists.newArrayList(memberId));
notifyRo.setFromUserId(String.valueOf(user.getId()));
Dict extras = Dict.create().set("nickName", user.getNickName());
- JSONObject data = JSONUtil.createObj().putOnce(NotificationConstants.BODY_EXTRAS, extras)
- .set("nickName", user.getNickName());
+ JSONObject data = JSONUtil.createObj()
+ .putOnce(NotificationConstants.BODY_EXTRAS, extras)
+ .set("nickName", user.getNickName());
notifyRo.setBody(data);
- notifyRo.setTemplateId(NotificationTemplateId.MEMBER_APPLIED_TO_CLOSE_ACCOUNT.getValue());
+ notifyRo.setTemplateId(NotificationTemplateId
+ .MEMBER_APPLIED_TO_CLOSE_ACCOUNT.getValue());
ros.add(notifyRo);
});
return ros;
}
- private void updateIsPaused(Long userId, boolean isPaused) {
+ private void updateIsPaused(final Long userId, final boolean isPaused) {
UserEntity userPaused = UserEntity.builder()
.id(userId).isPaused(isPaused).build();
baseMapper.updateById(userPaused);
}
+ /**
+ * *
+ * @param user UserEntity
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void cancelClosingAccount(UserEntity user) {
+ public void cancelClosingAccount(final UserEntity user) {
// Update the user to log off the cool down period status to No
updateIsPaused(user.getId(), false);
- // Get the member information that has not been logically deleted and the exceptions caused by compatible address book synchronization
- List unexpectedMembers = iMemberService.getByUserId(user.getId());
- List unexpectedMemberIds = unexpectedMembers.stream().map(MemberEntity::getId)
- .collect(Collectors.toList());
+ // Get the member information that has not been logically deleted
+ // and the exceptions caused by compatible address book synchronization
+ List unexpectedMembers =
+ iMemberService.getByUserId(user.getId());
+ List unexpectedMemberIds = unexpectedMembers.stream()
+ .map(MemberEntity::getId).collect(Collectors.toList());
// Logical deletion of abnormal member information
if (unexpectedMemberIds.size() > 0) {
memberMapper.deleteBatchByIds(unexpectedMemberIds);
@@ -816,23 +1108,31 @@ public class UserServiceImpl extends ServiceImpl impleme
loginUserCacheService.delete(user.getId());
userActiveSpaceCacheService.delete(user.getId());
// Add User Operation Record
- UserHistoryEntity userHistory = UserHistoryEntity.builder().userId(user.getId())
- .userStatus(UserOperationType.CANCEL_CLOSING.getStatusCode())
- .uuid(user.getUuid())
- .build();
+ UserHistoryEntity userHistory = UserHistoryEntity.builder()
+ .userId(user.getId())
+ .userStatus(UserOperationType.CANCEL_CLOSING.getStatusCode())
+ .uuid(user.getUuid())
+ .build();
iUserHistoryService.create(userHistory);
}
+ /**
+ * *
+ * @param user UserEntity
+ */
@Override
@Transactional(rollbackFor = Exception.class)
- public void closeAccount(UserEntity user) {
- // Clear the user's nickname, area code, mobile phone and email information
+ public void closeAccount(final UserEntity user) {
+ // Clear the user's nickname, area code,
+ // mobile phone and email information
userMapper.resetUserById(user.getId());
// Clear the user's information in the member table
memberMapper.clearMemberInfoByUserId(user.getId());
- // Physically delete the user's third-party association binding information
+ // Physically delete
+ // the user's third-party association binding information
socialServiceFacade.deleteUser(user.getId());
- // Write the "Logout Completed" record to the history table. 0 represents the system user
+ // Write the "Logout Completed" record to the history table.
+ // 0 represents the system user
UserHistoryEntity userHistory = UserHistoryEntity.builder()
.userId(user.getId())
.uuid(user.getUuid())
@@ -843,12 +1143,18 @@ public class UserServiceImpl extends ServiceImpl impleme
iUserHistoryService.create(userHistory);
}
+ /**
+ * *
+ * @param userIds User ID List
+ * @return List
+ */
@Override
- public List getPausedUserDtos(List userIds) {
+ public List getPausedUserDtos(final List userIds) {
return userMapper.selectPausedUsers(userIds);
}
- private boolean inactiveMemberProcess(Long userId, List inactiveMembers) {
+ private boolean inactiveMemberProcess(final Long userId,
+ final List inactiveMembers) {
if (CollUtil.isEmpty(inactiveMembers)) {
return false;
}
@@ -858,15 +1164,16 @@ public class UserServiceImpl extends ServiceImpl impleme
List spaceIds = iMemberService.getSpaceIdByUserId(userId);
inactiveMembers.forEach(member -> {
if (spaceIds.contains(member.getSpaceId())) {
- // An inactive member already exists in the user space. Delete the inactive member
+ // An inactive member already exists in the user space.
+ // Delete the inactive member
delMember.add(member.getId());
- }
- else {
+ } else {
activateMember.add(member.getId());
}
});
if (CollUtil.isNotEmpty(activateMember)) {
- // Activate members of the invited space and synchronize user information
+ // Activate members of the invited space
+ // and synchronize user information
UserEntity entity = getById(userId);
if (entity != null) {
List updateMembers = new ArrayList<>();
@@ -890,32 +1197,33 @@ public class UserServiceImpl extends ServiceImpl impleme
return true;
}
- private String getRandomAvatar() {
- String defaultAvatarList = constProperties.getDefaultAvatarList();
- if (StrUtil.isBlank(defaultAvatarList)) {
- return null;
- }
- String[] splits = defaultAvatarList.split(",");
- if (splits.length == 0) {
- return null;
- }
- return splits[RandomUtil.randomInt(0, splits.length)];
- }
-
+ /**
+ * *
+ * @param expectedLang The user did not set the system language.
+ * @param emails Email list
+ * @return List
+ */
@Override
- public List getLangByEmails(String expectedLang, List emails) {
+ public List getLangByEmails(final String expectedLang,
+ final List emails) {
// Maybe have performance problems, the segmented query is used.
List userLangs = new ArrayList<>(emails.size());
- int page = PageUtil.totalPage(emails.size(), QUERY_LOCALE_IN_EMAILS_LIMIT);
+ int page =
+ PageUtil.totalPage(emails.size(), QUERY_LOCALE_IN_EMAILS_LIMIT);
for (int i = 0; i < page; i++) {
- List subEmails = CollUtil.page(i, QUERY_LOCALE_IN_EMAILS_LIMIT, emails);
- userLangs.addAll(userMapper.selectLocaleInEmailsWithDefaultLocale(expectedLang, subEmails));
+ List subEmails =
+ CollUtil.page(i, QUERY_LOCALE_IN_EMAILS_LIMIT, emails);
+ userLangs.addAll(
+ userMapper.selectLocaleInEmailsWithDefaultLocale(expectedLang,
+ subEmails));
}
// Add an email that is not in the database
if (userLangs.size() != emails.size()) {
// Generally, they will not enter this judgment
- List existEmails = userLangs.stream().map(UserLangDTO::getEmail).collect(Collectors.toList());
- List nonExistEmails = CollUtil.subtractToList(emails, existEmails);
+ List existEmails = userLangs.stream()
+ .map(UserLangDTO::getEmail).collect(Collectors.toList());
+ List nonExistEmails =
+ CollUtil.subtractToList(emails, existEmails);
nonExistEmails.forEach(email -> {
UserLangDTO userLangDTO = new UserLangDTO();
userLangDTO.setLocale(expectedLang);
@@ -926,17 +1234,33 @@ public class UserServiceImpl extends ServiceImpl impleme
return userLangs;
}
+ /**
+ * *
+ * @param expectedLang The user did not set the system language.
+ * @param email Email
+ * @return The email sending language
+ */
@Override
- public String getLangByEmail(String expectedLang, String email) {
- UserLangDTO userLangDTO = userMapper.selectLocaleByEmailWithDefaultLocale(expectedLang, email);
+ public String getLangByEmail(
+ final String expectedLang, final String email) {
+ UserLangDTO userLangDTO =
+ userMapper.selectLocaleByEmailWithDefaultLocale(expectedLang,
+ email);
if (ObjectUtil.isNotNull(userLangDTO)) {
return userLangDTO.getLocale();
}
return expectedLang;
}
+ /**
+ * *
+ * @param userIds User ID
+ * @param defaultLocale Default Language
+ * @return List
+ */
@Override
- public List getLangAndEmailByIds(List userIds, String defaultLocale) {
+ public List getLangAndEmailByIds(
+ final List userIds, final String defaultLocale) {
List dtos = userMapper.selectLocaleAndEmailByIds(userIds);
return dtos.stream().peek(v -> {
if (StrUtil.isBlank(v.getLocale())) {
@@ -945,21 +1269,28 @@ public class UserServiceImpl extends ServiceImpl impleme
}).collect(Collectors.toList());
}
+ /**
+ * *
+ * @param uuid User uuid
+ * @return user id
+ */
@Override
- public Long getUserIdByUuid(String uuid) {
+ public Long getUserIdByUuid(final String uuid) {
return userMapper.selectIdByUuid(uuid);
}
- private String nullToDefaultNickName(String nickName, String mobileOrEmailPrefix) {
+ private String nullToDefaultNickName(
+ final String nickName, final String mobileOrEmailPrefix
+ ) {
return StrUtil.blankToDefault(nickName, mobileOrEmailPrefix);
}
- private String nullToDefaultAvatar(String avatar) {
+ private String nullToDefaultAvatar(final String avatar) {
return StrUtil.blankToDefault(avatar, null);
}
/**
- * Query users by username
+ * Query users by username.
* User's name can be email or area code+mobile phone number
*
* @param areaCode Area code
@@ -967,21 +1298,22 @@ public class UserServiceImpl extends ServiceImpl impleme
* @return UserEntity
*/
@Override
- public UserEntity getByUsername(String areaCode, String username) {
+ public UserEntity getByUsername(
+ final String areaCode, final String username
+ ) {
if (Validator.isEmail(username)) {
// Judge whether it exists
UserEntity user = this.getByEmail(username);
ExceptionUtil.isNotNull(user, USERNAME_OR_PASSWORD_ERROR);
return user;
- }
- else if (StrUtil.isNotBlank(areaCode)) {
- ExceptionUtil.isTrue(Validator.isNumber(username), USERNAME_OR_PASSWORD_ERROR);
+ } else if (StrUtil.isNotBlank(areaCode)) {
+ ExceptionUtil.isTrue(Validator.isNumber(username),
+ USERNAME_OR_PASSWORD_ERROR);
// Judge whether it exists
UserEntity user = this.getByCodeAndMobilePhone(areaCode, username);
ExceptionUtil.isNotNull(user, USERNAME_OR_PASSWORD_ERROR);
return user;
- }
- else {
+ } else {
// User name format error
throw new BusinessException(USERNAME_OR_PASSWORD_ERROR);
}
diff --git a/backend-server/application/src/main/java/com/apitable/user/service/impl/package-info.java b/backend-server/application/src/main/java/com/apitable/user/service/impl/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c04bcae2370089c93d247dc65586102e1010c0b
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/user/service/impl/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * APITable
+ * Copyright (C) 2022 APITable Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ *
+ * @author Chambers
+ */
+package com.apitable.user.service.impl;
diff --git a/backend-server/application/src/main/java/com/apitable/widget/controller/WidgetController.java b/backend-server/application/src/main/java/com/apitable/widget/controller/WidgetController.java
new file mode 100644
index 0000000000000000000000000000000000000000..ec4f9ab4e244b4c96e1d66208dff997b6b6d2604
--- /dev/null
+++ b/backend-server/application/src/main/java/com/apitable/widget/controller/WidgetController.java
@@ -0,0 +1,225 @@
+/*
+ * APITable
+ * Copyright (C) 2022 APITable Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.apitable.widget.controller;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+import cn.hutool.core.util.StrUtil;
+import com.apitable.base.enums.ParameterException;
+import com.apitable.control.infrastructure.ControlTemplate;
+import com.apitable.control.infrastructure.permission.NodePermission;
+import com.apitable.core.support.ResponseData;
+import com.apitable.core.util.ExceptionUtil;
+import com.apitable.widget.ro.WidgetStoreListRo;
+import com.apitable.widget.vo.WidgetStoreListInfo;
+import com.apitable.shared.cache.service.UserSpaceCacheService;
+import com.apitable.shared.component.scanner.annotation.ApiResource;
+import com.apitable.shared.component.scanner.annotation.GetResource;
+import com.apitable.shared.component.scanner.annotation.PostResource;
+import com.apitable.shared.constants.ParamsConstants;
+import com.apitable.shared.context.LoginContext;
+import com.apitable.shared.context.SessionContext;
+import com.apitable.space.service.ISpaceService;
+import com.apitable.widget.enums.WidgetException;
+import com.apitable.widget.mapper.WidgetMapper;
+import com.apitable.widget.mapper.WidgetPackageMapper;
+import com.apitable.widget.ro.WidgetCopyRo;
+import com.apitable.widget.ro.WidgetCreateRo;
+import com.apitable.widget.service.IWidgetService;
+import com.apitable.widget.vo.WidgetInfo;
+import com.apitable.widget.vo.WidgetPack;
+import com.apitable.widget.vo.WidgetTemplatePackageInfo;
+import com.apitable.workspace.service.INodeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import static com.apitable.workspace.enums.PermissionException.NODE_OPERATION_DENIED;
+
+@RestController
+@Api(tags = "Widget SDK - Widget Api")
+@ApiResource(path = "/")
+public class WidgetController {
+
+ @Resource
+ private ISpaceService iSpaceService;
+
+ @Resource
+ private INodeService iNodeService;
+
+ @Resource
+ private ControlTemplate controlTemplate;
+
+ @Resource
+ private UserSpaceCacheService userSpaceCacheService;
+
+ @Resource
+ private IWidgetService iWidgetService;
+
+ @Resource
+ private WidgetPackageMapper widgetPackageMapper;
+
+ @Resource
+ private WidgetMapper widgetMapper;
+
+ @PostResource(path = "/widget/package/store/list", requiredPermission = false)
+ @ApiOperation(value = "Get widget store")
+ @ApiImplicitParam(name = ParamsConstants.SPACE_ID, value = "space id", required = true, dataTypeClass = String.class, paramType = "header", example = "spczJrh2i3tLW")
+ public ResponseData> widgetStoreList(@RequestBody @Valid WidgetStoreListRo storeListRo) {
+ Long userId = SessionContext.getUserId();
+ String spaceId = LoginContext.me().getSpaceId();
+ String userLocale = LocaleContextHolder.getLocale().toLanguageTag();
+ storeListRo.setLanguage(Optional.ofNullable(storeListRo.getLanguage()).orElse(userLocale));
+ List infos = iWidgetService.widgetStoreList(userId, spaceId, storeListRo);
+ return ResponseData.success(infos);
+ }
+
+ @GetResource(path = "/space/{spaceId}/widget", requiredPermission = false)
+ @ApiOperation(value = "Get the space widgets", notes = "get the widgets under the entire space")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "spaceId", value = "space id", required = true, dataTypeClass = String.class, paramType = "path", example = "spczJrh2i3tLW"),
+ @ApiImplicitParam(name = "count", value = "load quantity", dataTypeClass = Integer.class, paramType = "query", example = "10")
+ })
+ public ResponseData> findWidgetInfoBySpaceId(@PathVariable("spaceId") String spaceId,
+ @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) {
+ Long userId = SessionContext.getUserId();
+ Long memberId = userSpaceCacheService.getMemberId(userId, spaceId);
+ List infos = iWidgetService.getWidgetInfoList(spaceId, memberId, count);
+ return ResponseData.success(infos);
+ }
+
+ @GetResource(path = "/node/{nodeId}/widget", requiredPermission = false)
+ @ApiOperation(value = "get the widget information of the node")
+ @ApiImplicitParam(name = "nodeId", value = "node id", required = true, dataTypeClass = String.class, paramType = "path", example = "dstJ2oRZxsh2yld4MA")
+ public ResponseData> findWidgetInfoByNodeId(@PathVariable("nodeId") String nodeId) {
+ Long userId = SessionContext.getUserId();
+ // Determine whether the node does not exist or cross-spatial access
+ String spaceId = iNodeService.getSpaceIdByNodeId(nodeId);
+ Long memberId = userSpaceCacheService.getMemberId(userId, spaceId);
+ // check permission
+ controlTemplate.checkNodePermission(memberId, nodeId, NodePermission.READ_NODE,
+ status -> ExceptionUtil.isTrue(status, NODE_OPERATION_DENIED));
+ List infos = widgetMapper.selectInfoByNodeId(nodeId);
+ return ResponseData.success(infos);
+ }
+
+ @GetResource(path = "/node/{nodeId}/widgetPack", requiredLogin = false)
+ @ApiOperation(value = "Get the node widget package", notes = "Node types are limited to dashboards and datasheet")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = ParamsConstants.SPACE_ID, value = "space id", dataTypeClass = String.class, paramType = "header", example = "spczJrh2i3tLW"),
+ @ApiImplicitParam(name = "nodeId", value = "node id", required = true, dataTypeClass = String.class, paramType = "path", example = "dstJ2oRZxsh2yld4MA"),
+ @ApiImplicitParam(name = "linkId", value = "association id:node share id、template id", dataTypeClass = String.class, paramType = "query", example = "shr8T8vAfehg3yj3McmDG")
+ })
+ public ResponseData> findWidgetPackByNodeId(@PathVariable("nodeId") String nodeId,
+ @RequestParam(value = "linkId", required = false) String linkId) {
+ // Determine whether the node does not exist or cross-spatial access
+ String nodeSpaceId = iNodeService.checkNodeIfExist(null, nodeId);
+ if (StrUtil.isBlank(linkId)) {
+ // check permission
+ Long userId = SessionContext.getUserId();
+ Long memberId = userSpaceCacheService.getMemberId(userId, nodeSpaceId);
+ controlTemplate.checkNodePermission(memberId, nodeId, NodePermission.READ_NODE,
+ status -> ExceptionUtil.isTrue(status, NODE_OPERATION_DENIED));
+ }
+ else {
+ // out of station access
+ String spaceId = iSpaceService.getSpaceIdByLinkId(linkId);
+ ExceptionUtil.isTrue(nodeSpaceId.equals(spaceId), WidgetException.WIDGET_SPACE_ERROR);
+ }
+ // get all components under the node
+ List widgetIds = widgetMapper.selectWidgetIdsByNodeId(nodeId);
+ return ResponseData.success(iWidgetService.getWidgetPackList(widgetIds));
+ }
+
+ @GetResource(path = "/widget/get", requiredLogin = false)
+ @ApiOperation(value = "Get widget info", notes = "get widget info by widget id")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "widgetIds", value = "widget ids", required = true, dataTypeClass = String.class, paramType = "query", example = "wdtlMDweJzTsbSJAFY,wdt923ZpvvRhD8kVLs"),
+ @ApiImplicitParam(name = "linkId", value = "Association ID: node sharing ID and template ID", dataTypeClass = String.class, paramType = "query", example = "shr8T8vAfehg3yj3McmDG")
+ })
+ public ResponseData> findWidgetPackByWidgetIds(@RequestParam("widgetIds") List widgetIds,
+ @RequestParam(value = "linkId", required = false) String linkId) {
+ ExceptionUtil.isNotEmpty(widgetIds, ParameterException.INCORRECT_ARG);
+ String widgetSpaceId = iWidgetService.checkByWidgetIds(widgetIds);
+ if (StrUtil.isBlank(linkId)) {
+ Long userId = SessionContext.getUserId();
+ // prevent access to unadded spaces
+ userSpaceCacheService.getMemberId(userId, widgetSpaceId);
+ }
+ else {
+ // out of station access
+ String spaceId = iSpaceService.getSpaceIdByLinkId(linkId);
+ ExceptionUtil.isTrue(widgetSpaceId.equals(spaceId), WidgetException.WIDGET_SPACE_ERROR);
+ }
+ return ResponseData.success(iWidgetService.getWidgetPackList(widgetIds));
+ }
+
+ @PostResource(path = "/widget/create", requiredPermission = false)
+ @ApiOperation(value = "Create widget", notes = "Scenario:1、dashboard new applet 2、datasheet widget panel new widget")
+ public ResponseData createWidget(@RequestBody @Valid WidgetCreateRo widget) {
+ Long userId = SessionContext.getUserId();
+ // The method includes determining whether a node exists.
+ String spaceId = iNodeService.getSpaceIdByNodeId(widget.getNodeId());
+ // The method includes determining whether the user is in this space.
+ Long memberId = LoginContext.me().getMemberId(userId, spaceId);
+ // check permission
+ controlTemplate.checkNodePermission(memberId, widget.getNodeId(), NodePermission.MANAGE_NODE,
+ status -> ExceptionUtil.isTrue(status, NODE_OPERATION_DENIED));
+ // create widget
+ String widgetId = iWidgetService.create(userId, spaceId, widget);
+ return ResponseData.success(iWidgetService.getWidgetPack(widgetId));
+ }
+
+ @PostResource(path = "/widget/copy", requiredPermission = false)
+ @ApiOperation(value = "Copy widget", notes = "Scenario: 1、dashboard import widget 2、the widget panel sends applets to the dashboard")
+ public ResponseData> copyWidget(@RequestBody @Valid WidgetCopyRo widgetRo) {
+ Long userId = SessionContext.getUserId();
+ // The method includes determining whether a node exists.
+ String spaceId = iNodeService.getSpaceIdByNodeId(widgetRo.getDashboardId());
+ // The method includes determining whether the user is in this space.
+ Long memberId = LoginContext.me().getMemberId(userId, spaceId);
+ // check permission
+ controlTemplate.checkNodePermission(memberId, widgetRo.getDashboardId(), NodePermission.MANAGE_NODE,
+ status -> ExceptionUtil.isTrue(status, NODE_OPERATION_DENIED));
+ // copy widget
+ Collection widgetIds = iWidgetService.copyToDashboard(userId, spaceId, widgetRo.getDashboardId(), widgetRo.getWidgetIds());
+ return ResponseData.success(iWidgetService.getWidgetPackList(widgetIds));
+ }
+
+ @GetResource(path = "/widget/template/package/list", requiredPermission = false)
+ @ApiOperation(value = "Get package teamplates")
+ public ResponseData