New file |
| | |
| | | package kr.wisestone.owl.annotation; |
| | | |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | @Target({ElementType.TYPE}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | @Component |
| | | public @interface Viewer { |
| | | String value() default ""; |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.common; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.WebAppUtil; |
| | | import kr.wisestone.owl.vo.ExportExcelAttrVo; |
| | | import kr.wisestone.owl.vo.ExportExcelVo; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.messaging.simp.SimpMessagingTemplate; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.IOException; |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-12-18. |
| | | */ |
| | | @Component |
| | | public class ExcelConditionCheck { |
| | | |
| | | @Autowired |
| | | private SimpMessagingTemplate simpMessagingTemplate; |
| | | |
| | | @Autowired |
| | | private WebAppUtil webAppUtil; |
| | | |
| | | @Autowired |
| | | private MessageAccessor messageAccessor; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | public ModelAndView checkCondition(Map<String, Object> conditions, HttpServletRequest request, Model model) { |
| | | Map<String, Object> results; |
| | | |
| | | try { |
| | | results = CommonUtil.getSearchConditions(request); |
| | | Iterator iterator = results.keySet().iterator(); |
| | | |
| | | while(iterator.hasNext()) { |
| | | String key = (String)iterator.next(); |
| | | Object value = results.get(key); |
| | | conditions.put(key, value); |
| | | } |
| | | } |
| | | catch(IOException e) { |
| | | ExportExcelVo excelInfo = this.makeEmptyDownloadExcel(); |
| | | excelInfo.setFileName("검색 조건 오류 - 와이즈스톤 담당자에게 문의하세요."); |
| | | this.simpMessagingTemplate.convertAndSendToUser(this.webAppUtil.getLoginUser().getAccount(), "/notification/system-alert", this.messageAccessor.getMessage(MsgConstants.EXCEL_CONDITIONS_NOT_EXIST)); |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | public ExportExcelVo makeEmptyDownloadExcel() { |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("name", "", 120, ExportExcelAttrVo.ALIGN_LEFT)); |
| | | return excelInfo; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.common; |
| | | |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.vo.MessageVo; |
| | | import kr.wisestone.owl.vo.ResMessageVo; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.i18n.LocaleContextHolder; |
| | | import org.springframework.context.support.MessageSourceAccessor; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.servlet.LocaleResolver; |
| | | |
| | | import java.util.Locale; |
| | | |
| | | @Component |
| | | public class MessageAccessor { |
| | | @Autowired |
| | | private MessageSourceAccessor messageSourceAccessor; |
| | | |
| | | @Autowired |
| | | private LocaleResolver localeResolver; |
| | | |
| | | public MessageSourceAccessor getMessageSourceAccessor() { |
| | | return messageSourceAccessor; |
| | | } |
| | | |
| | | public String message(String code, Locale locale) { |
| | | return this.messageSourceAccessor.getMessage(code, locale); |
| | | } |
| | | |
| | | public String message(String code, Object... args) { |
| | | return this.messageSourceAccessor.getMessage(code, args, LocaleContextHolder.getLocale()); |
| | | } |
| | | |
| | | public MessageVo getMessage(String code, Object... args) { |
| | | return new MessageVo(code, this.messageSourceAccessor.getMessage(code, args, LocaleContextHolder.getLocale())); |
| | | } |
| | | |
| | | public ResMessageVo getResMessage(String code, String status, Object... args) { |
| | | return new ResMessageVo(this.messageSourceAccessor.getMessage(code, args, LocaleContextHolder.getLocale()), code, status); |
| | | } |
| | | |
| | | public Object getResMessage(OwlRuntimeException ex, String status) { |
| | | return new ResMessageVo(ex.getMessage(), ex.getCode(), status); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import org.mybatis.spring.annotation.MapperScan; |
| | | import org.springframework.context.annotation.ComponentScan; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-08-01. |
| | | */ |
| | | @Configuration |
| | | @ComponentScan(basePackages = "kr.wisestone.owl") |
| | | @MapperScan(basePackages = "kr.wisestone.owl.mapper") |
| | | public class AppConfiguration { |
| | | |
| | | } |
New file |
| | |
| | | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component("") |
| | | public class ApplicationContextProvider implements ApplicationContextAware { |
| | | private static ApplicationContext context; |
| | | |
| | | public static ApplicationContext getContext() { |
| | | return context; |
| | | } |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext ctx) throws BeansException { |
| | | context = ctx; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; |
| | | import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.scheduling.TaskScheduler; |
| | | import org.springframework.scheduling.annotation.AsyncConfigurer; |
| | | import org.springframework.scheduling.annotation.EnableAsync; |
| | | import org.springframework.scheduling.annotation.EnableScheduling; |
| | | import org.springframework.scheduling.annotation.SchedulingConfigurer; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; |
| | | import org.springframework.scheduling.config.ScheduledTaskRegistrar; |
| | | import org.springframework.util.ErrorHandler; |
| | | import java.util.concurrent.RejectedExecutionHandler; |
| | | import java.util.concurrent.ThreadPoolExecutor; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-07-26. |
| | | */ |
| | | @Configuration |
| | | @EnableScheduling |
| | | @EnableAsync(order= Ordered.HIGHEST_PRECEDENCE) |
| | | public class AsyncConfiguration implements AsyncConfigurer, SchedulingConfigurer { |
| | | |
| | | private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class); |
| | | |
| | | private static final String CORE_POOL_SIZE = "10"; |
| | | |
| | | private static final String MAX_POOL_SIZE = "100"; |
| | | |
| | | private static final String QUEUE_CAPACITY = "100000"; |
| | | |
| | | @Override |
| | | @Bean(name = "taskExecutor") |
| | | public ThreadPoolTaskExecutor getAsyncExecutor() { |
| | | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); |
| | | executor.setCorePoolSize(Integer.parseInt(CORE_POOL_SIZE)); |
| | | executor.setMaxPoolSize(Integer.parseInt(MAX_POOL_SIZE)); |
| | | executor.setQueueCapacity(Integer.parseInt(QUEUE_CAPACITY)); |
| | | executor.setThreadNamePrefix("owl-Executor-"); |
| | | return executor; |
| | | } |
| | | |
| | | @Bean |
| | | public ThreadPoolTaskScheduler taskScheduler() { |
| | | ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); |
| | | scheduler.setPoolSize(20); |
| | | scheduler.setThreadNamePrefix("task-"); |
| | | scheduler.setAwaitTerminationSeconds(60); |
| | | scheduler.setWaitForTasksToCompleteOnShutdown(true); |
| | | scheduler.setErrorHandler(new ErrorHandler() { |
| | | @Override |
| | | public void handleError(Throwable t) { |
| | | log.error("task 실행시 알 수 없는 에러가 발생했습니다.", t); |
| | | } |
| | | }); |
| | | scheduler.setRejectedExecutionHandler(new RejectedExecutionHandler() { |
| | | @Override |
| | | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { |
| | | log.error("알 수 없는 이유로 task 실행이 거절되었습니다.", r); |
| | | } |
| | | }); |
| | | |
| | | return scheduler; |
| | | } |
| | | |
| | | @Override |
| | | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { |
| | | return new SimpleAsyncUncaughtExceptionHandler(); |
| | | } |
| | | |
| | | @Override |
| | | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { |
| | | TaskScheduler taskScheduler = this.taskScheduler(); |
| | | taskRegistrar.setTaskScheduler(taskScheduler); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import com.amazonaws.ClientConfiguration; |
| | | import com.amazonaws.Protocol; |
| | | import com.amazonaws.auth.AWSStaticCredentialsProvider; |
| | | import com.amazonaws.auth.BasicAWSCredentials; |
| | | import com.amazonaws.regions.Regions; |
| | | import com.amazonaws.services.s3.AmazonS3; |
| | | import com.amazonaws.services.s3.AmazonS3ClientBuilder; |
| | | import kr.wisestone.owl.util.PageUtil; |
| | | import kr.wisestone.owl.util.WebAppUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.context.annotation.Profile; |
| | | import org.springframework.context.support.MessageSourceAccessor; |
| | | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; |
| | | import org.springframework.context.support.ReloadableResourceBundleMessageSource; |
| | | import org.springframework.core.io.ClassPathResource; |
| | | import org.springframework.mail.javamail.JavaMailSender; |
| | | import org.springframework.mail.javamail.JavaMailSenderImpl; |
| | | import org.springframework.session.FindByIndexNameSessionRepository; |
| | | import org.springframework.session.security.SpringSessionBackedSessionRegistry; |
| | | |
| | | import java.util.Properties; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-08-14. |
| | | */ |
| | | @Configuration |
| | | public class CommonConfiguration { |
| | | |
| | | private static final String FILE_ENCODING = "UTF-8"; |
| | | private static final String MAIL_DEBUG = "mail.debug"; |
| | | private static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable"; |
| | | private static final String MAIL_SMTP_AUTH = "mail.smtp.auth"; |
| | | private static final String MAIL_SMTP_SSL_TRUST = "mail.smtp.ssl.trust"; |
| | | |
| | | @Value("${aws.access.key}") |
| | | private String accessKey; |
| | | |
| | | @Value("${aws.access.password}") |
| | | private String accessPassword; |
| | | |
| | | @Autowired |
| | | private FindByIndexNameSessionRepository findByIndexNameSessionRepository; |
| | | |
| | | @Value("${email.host}") |
| | | private String emailHost; |
| | | @Value("${email.port}") |
| | | private String emailPort; |
| | | @Value("${email.userName}") |
| | | private String emailUserName; |
| | | @Value("${email.password}") |
| | | private String emailPassword; |
| | | @Value("${email.transport.protocol}") |
| | | private String emailTransportProtocol; |
| | | @Value("${email.smtp.auth}") |
| | | private String emailSmtpAuth; |
| | | @Value("${email.smtp.starttle.enable}") |
| | | private String emailSmtpStarttleEnable; |
| | | @Value("${email.debug}") |
| | | private String emailDebug; |
| | | @Value("${email.sendUrl}") |
| | | private String emailSendUrl; |
| | | |
| | | @Bean |
| | | public WebAppUtil webAppUtil() { |
| | | return new WebAppUtil(); |
| | | } |
| | | |
| | | @Bean |
| | | public PageUtil pageUtil() { |
| | | return new PageUtil(); |
| | | } |
| | | |
| | | @Profile("prod") |
| | | @Bean |
| | | public static PropertySourcesPlaceholderConfigurer prodProperties() { |
| | | PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); |
| | | configurer.setLocations(new ClassPathResource("system_prod.properties")); |
| | | configurer.setFileEncoding(FILE_ENCODING); |
| | | |
| | | return configurer; |
| | | } |
| | | |
| | | @Profile("dev") |
| | | @Bean |
| | | public static PropertySourcesPlaceholderConfigurer devProperties() { |
| | | PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); |
| | | configurer.setLocations(new ClassPathResource("system_dev.properties")); |
| | | configurer.setFileEncoding(FILE_ENCODING); |
| | | |
| | | return configurer; |
| | | } |
| | | |
| | | @Profile("test") |
| | | @Bean |
| | | public static PropertySourcesPlaceholderConfigurer testProperties() { |
| | | PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); |
| | | configurer.setLocations(new ClassPathResource("system_test.properties")); |
| | | configurer.setFileEncoding(FILE_ENCODING); |
| | | |
| | | return configurer; |
| | | } |
| | | |
| | | @Profile("design") |
| | | @Bean |
| | | public static PropertySourcesPlaceholderConfigurer designProperties() { |
| | | PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); |
| | | configurer.setLocations(new ClassPathResource("system_design.properties")); |
| | | configurer.setFileEncoding(FILE_ENCODING); |
| | | |
| | | return configurer; |
| | | } |
| | | |
| | | @Bean |
| | | public String getEmailSendUrl() { return this.emailSendUrl; } |
| | | |
| | | @Bean |
| | | public MessageSourceAccessor messageSourceAccessor(ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource) { |
| | | return new MessageSourceAccessor(reloadableResourceBundleMessageSource); |
| | | } |
| | | |
| | | @Bean |
| | | public ReloadableResourceBundleMessageSource messageSource() { |
| | | ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); |
| | | messageSource.setCacheSeconds(10); |
| | | messageSource.setDefaultEncoding(FILE_ENCODING); |
| | | messageSource.setBasenames("/WEB-INF/i18n/messages", "/WEB-INF/i18n/mail", "/WEB-INF/i18n/code"); |
| | | messageSource.setUseCodeAsDefaultMessage(true); |
| | | |
| | | return messageSource; |
| | | } |
| | | |
| | | @Bean |
| | | public JavaMailSender javaMailSender() { |
| | | JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); |
| | | javaMailSender.setHost(this.emailHost); |
| | | javaMailSender.setPort(Integer.valueOf(this.emailPort)); |
| | | javaMailSender.setUsername(this.emailUserName); |
| | | javaMailSender.setPassword(this.emailPassword); |
| | | |
| | | Properties javaMailProperties = new Properties(); |
| | | javaMailProperties.setProperty(MAIL_SMTP_SSL_TRUST, this.emailHost); |
| | | javaMailProperties.setProperty(MAIL_SMTP_AUTH, this.emailSmtpAuth); |
| | | javaMailProperties.setProperty(MAIL_SMTP_STARTTLS_ENABLE, this.emailSmtpStarttleEnable); |
| | | javaMailProperties.setProperty(MAIL_DEBUG, this.emailDebug); |
| | | javaMailSender.setJavaMailProperties(javaMailProperties); |
| | | |
| | | return javaMailSender; |
| | | } |
| | | |
| | | @Bean |
| | | public AmazonS3 amazonS3() { |
| | | BasicAWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.accessPassword); |
| | | ClientConfiguration clientConfiguration = new ClientConfiguration(); |
| | | clientConfiguration.setProtocol(Protocol.HTTP); |
| | | |
| | | return AmazonS3ClientBuilder |
| | | .standard() |
| | | .withRegion(Regions.AP_NORTHEAST_2) |
| | | .withCredentials(new AWSStaticCredentialsProvider(credentials)) |
| | | .withClientConfiguration(clientConfiguration).build(); |
| | | } |
| | | |
| | | @Bean |
| | | @SuppressWarnings("unchecked") |
| | | public SpringSessionBackedSessionRegistry sessionRegistry() { |
| | | return new SpringSessionBackedSessionRegistry(this.findByIndexNameSessionRepository); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import com.zaxxer.hikari.HikariConfig; |
| | | import com.zaxxer.hikari.HikariDataSource; |
| | | import kr.wisestone.owl.config.persistence.aop.TransactionDefinitionInterceptor; |
| | | import kr.wisestone.owl.config.persistence.routing.TransactionDefinitionRoutingDataSource; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.ibatis.session.SqlSessionFactory; |
| | | import org.flywaydb.core.Flyway; |
| | | import org.mybatis.spring.SqlSessionFactoryBean; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.context.annotation.EnableAspectJAutoProxy; |
| | | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
| | | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; |
| | | import org.springframework.orm.jpa.JpaTransactionManager; |
| | | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; |
| | | import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; |
| | | import org.springframework.transaction.PlatformTransactionManager; |
| | | import org.springframework.transaction.annotation.EnableTransactionManagement; |
| | | import org.springframework.transaction.annotation.TransactionManagementConfigurer; |
| | | import org.springframework.transaction.interceptor.TransactionAttributeSource; |
| | | |
| | | import javax.persistence.SharedCacheMode; |
| | | import javax.persistence.ValidationMode; |
| | | import javax.sql.DataSource; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-08-02. |
| | | */ |
| | | @Configuration |
| | | @EnableTransactionManagement |
| | | @EnableJpaRepositories( |
| | | basePackages = {"kr.wisestone.owl.repository"}, |
| | | entityManagerFactoryRef = "entityManagerFactory", |
| | | transactionManagerRef = "jpaTransactionManager" |
| | | ) |
| | | @EnableAspectJAutoProxy |
| | | public class DataBaseConfiguration implements TransactionManagementConfigurer { |
| | | |
| | | @Value("${db.primary.driverName}") |
| | | private String dbPrimaryDriverName; |
| | | @Value("${db.primary.url}") |
| | | private String dbPrimaryUrl; |
| | | @Value("${db.primary.userName}") |
| | | private String dbPrimaryUserName; |
| | | @Value("${db.primary.password}") |
| | | private String dbPrimaryPassword; |
| | | |
| | | @Value("${db.replica1.url}") |
| | | private String dbReplica1PrimaryUrl; |
| | | @Value("${db.replica2.url}") |
| | | private String dbReplica2PrimaryUrl; |
| | | @Value("${db.replica3.url}") |
| | | private String dbReplica3PrimaryUrl; |
| | | @Value("${db.replica4.url}") |
| | | private String dbReplica4PrimaryUrl; |
| | | @Value("${db.replica5.url}") |
| | | private String dbReplica5PrimaryUrl; |
| | | |
| | | @Bean |
| | | public TransactionDefinitionInterceptor transactionDefinitionInterceptor(TransactionAttributeSource transactionAttributeSource) { |
| | | return new TransactionDefinitionInterceptor(transactionAttributeSource); |
| | | } |
| | | |
| | | @Bean |
| | | public DataSource dataSource() { |
| | | final TransactionDefinitionRoutingDataSource transactionDefinitionRoutingDataSource = new TransactionDefinitionRoutingDataSource(); |
| | | final Map<Object, Object> targetDataSources = new HashMap<>(); |
| | | |
| | | this.setReplica(targetDataSources, this.dbReplica1PrimaryUrl, 1); |
| | | this.setReplica(targetDataSources, this.dbReplica2PrimaryUrl, 2); |
| | | this.setReplica(targetDataSources, this.dbReplica3PrimaryUrl, 3); |
| | | this.setReplica(targetDataSources, this.dbReplica4PrimaryUrl, 4); |
| | | this.setReplica(targetDataSources, this.dbReplica5PrimaryUrl, 5); |
| | | |
| | | transactionDefinitionRoutingDataSource.setDefaultTargetDataSource(this.buildDataSource("primaryHikariPool", this.dbPrimaryUrl, this.dbPrimaryUserName, this.dbPrimaryPassword, this.dbPrimaryDriverName)); // master db |
| | | transactionDefinitionRoutingDataSource.setTargetDataSources(targetDataSources); |
| | | return transactionDefinitionRoutingDataSource; |
| | | } |
| | | |
| | | // 리플리카 설정 |
| | | private void setReplica(Map<Object, Object> targetDataSources, String replicaUrl, int count) { |
| | | if (!StringUtils.isEmpty(replicaUrl)) { |
| | | targetDataSources.put("replica" + count, this.buildDataSource("replicaHikariPool" + count, replicaUrl, this.dbPrimaryUserName, this.dbPrimaryPassword, this.dbPrimaryDriverName)); |
| | | } |
| | | } |
| | | |
| | | private DataSource buildDataSource(String poolName, String jdbcUrl, String userName, String password, String driverClassName) { |
| | | HikariConfig hikariConfig = new HikariConfig(); |
| | | hikariConfig.setMinimumIdle(40); |
| | | hikariConfig.setConnectionTimeout(10000); |
| | | hikariConfig.setMaxLifetime(58000); |
| | | hikariConfig.setValidationTimeout(10000); |
| | | hikariConfig.setMaximumPoolSize(40); |
| | | hikariConfig.setConnectionTestQuery("SELECT 1"); |
| | | hikariConfig.setPoolName(poolName); |
| | | hikariConfig.setJdbcUrl(jdbcUrl); |
| | | hikariConfig.setUsername(userName); |
| | | hikariConfig.setPassword(password); |
| | | hikariConfig.setDriverClassName(driverClassName); |
| | | |
| | | return new HikariDataSource(hikariConfig); |
| | | } |
| | | |
| | | @Override |
| | | public PlatformTransactionManager annotationDrivenTransactionManager() { |
| | | return this.jpaTransactionManager(); |
| | | } |
| | | |
| | | @Bean |
| | | public PlatformTransactionManager jpaTransactionManager() { |
| | | JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); |
| | | jpaTransactionManager.setEntityManagerFactory(this.entityManagerFactory().getObject()); |
| | | return jpaTransactionManager; |
| | | } |
| | | |
| | | @Bean |
| | | public LocalContainerEntityManagerFactoryBean entityManagerFactory() { |
| | | HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); |
| | | adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); |
| | | |
| | | LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); |
| | | factory.setJpaVendorAdapter(adapter); |
| | | factory.setDataSource(this.dataSource()); |
| | | factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE); |
| | | factory.setValidationMode(ValidationMode.NONE); |
| | | factory.setPackagesToScan("kr.wisestone.owl.domain"); |
| | | factory.setMappingResources("META-INF/orm.xml"); |
| | | factory.setJpaPropertyMap(this.getJpaProperties()); |
| | | |
| | | return factory; |
| | | } |
| | | |
| | | private Map<String, Object> getJpaProperties() { |
| | | Map<String, Object> jpaProperties = new HashMap<>(); |
| | | jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect"); |
| | | jpaProperties.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver"); |
| | | jpaProperties.put("hibernate.physical_naming_strategy", "kr.wisestone.owl.domain.strategy.PrefixNamingStrategy"); |
| | | jpaProperties.put("hibernate.show_sql", "false"); |
| | | jpaProperties.put("hibernate.format_sql", "true"); |
| | | jpaProperties.put("hibernate.use_sql_comments", "true"); |
| | | jpaProperties.put("hibernate.session_factory.interceptor", "kr.wisestone.owl.domain.interceptor.AuditLogInterceptor"); |
| | | |
| | | return jpaProperties; |
| | | } |
| | | |
| | | @Bean |
| | | public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { |
| | | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); |
| | | |
| | | sqlSessionFactoryBean.setDataSource(dataSource); |
| | | sqlSessionFactoryBean.setConfigLocation( |
| | | new PathMatchingResourcePatternResolver().getResource("classpath:/mybatis/config/mybatis-config.xml") |
| | | ); |
| | | sqlSessionFactoryBean.setMapperLocations( |
| | | new PathMatchingResourcePatternResolver().getResources("classpath:/mybatis/query-template*//*.xml") |
| | | ); |
| | | |
| | | return sqlSessionFactoryBean.getObject(); |
| | | } |
| | | |
| | | @Bean(initMethod = "migrate") |
| | | public Flyway flyway(DataSource dataSource) { |
| | | Flyway flyway = new Flyway(); |
| | | flyway.setBaselineOnMigrate(true); |
| | | flyway.setLocations("classpath:/migration"); |
| | | flyway.setDataSource(dataSource); |
| | | |
| | | return flyway; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import org.apache.http.HttpHost; |
| | | import org.elasticsearch.client.RestClient; |
| | | import org.elasticsearch.client.RestHighLevelClient; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import java.util.Arrays; |
| | | |
| | | @Configuration |
| | | public class ElasticSearchConfiguration { |
| | | @Value("${elastic.search.hosts}") |
| | | private String hosts; |
| | | |
| | | @Bean |
| | | public RestHighLevelClient restHighLevelClient() { |
| | | String[] elasticSearchHosts = this.hosts.replaceAll("\\p{Z}", "").split(","); |
| | | |
| | | return new RestHighLevelClient( |
| | | RestClient.builder(Arrays.stream(elasticSearchHosts).map(HttpHost::create).toArray(HttpHost[]::new)) |
| | | ); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import kr.wisestone.owl.service.impl.AttachedFileServiceImpl; |
| | | import kr.wisestone.owl.config.kafka.KafkaReceiver; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.kafka.support.serializer.JsonDeserializer; |
| | | import org.springframework.kafka.support.serializer.JsonSerializer; |
| | | import org.apache.kafka.clients.consumer.ConsumerConfig; |
| | | import org.apache.kafka.clients.producer.ProducerConfig; |
| | | import org.apache.kafka.common.serialization.StringDeserializer; |
| | | import org.apache.kafka.common.serialization.StringSerializer; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.kafka.annotation.EnableKafka; |
| | | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; |
| | | import org.springframework.kafka.core.*; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | // edit by zenith : for disable kafka |
| | | //@EnableKafka |
| | | @Configuration |
| | | public class KafkaConfiguration { |
| | | private static final Logger LOGGER = LoggerFactory.getLogger(AttachedFileServiceImpl.class); |
| | | |
| | | @Value("${use.kafka}") |
| | | private boolean useKafka; |
| | | |
| | | @Value("${kafka.bootstrap.servers}") |
| | | private String bootstrapServers; |
| | | |
| | | @Value("${kafka.consumer.group.id}") |
| | | private String groupId; |
| | | |
| | | @Bean |
| | | public ProducerFactory<String, Object> producerFactory() { |
| | | Map<String, Object> configProps = new HashMap<>(); |
| | | configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, this.bootstrapServers); |
| | | configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); |
| | | configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); |
| | | return new DefaultKafkaProducerFactory<>(configProps); |
| | | } |
| | | |
| | | @Bean |
| | | public KafkaTemplate<String, Object> kafkaTemplate() { |
| | | return new KafkaTemplate<>(this.producerFactory()); |
| | | } |
| | | |
| | | @Bean |
| | | public ConsumerFactory<String, Object> consumerFactory() { |
| | | Map<String, Object> configProps = new HashMap<>(); |
| | | configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, this.bootstrapServers); |
| | | configProps.put(ConsumerConfig.GROUP_ID_CONFIG, this.groupId); |
| | | configProps.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true); |
| | | configProps.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 1000); |
| | | configProps.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 30000); |
| | | configProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); |
| | | configProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class); |
| | | |
| | | return new DefaultKafkaConsumerFactory<>(configProps); |
| | | } |
| | | |
| | | @Bean |
| | | public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() { |
| | | ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); |
| | | factory.setConsumerFactory(this.consumerFactory()); |
| | | return factory; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import kr.wisestone.owl.config.security.filter.AjaxSessionExpiredFilter; |
| | | import kr.wisestone.owl.config.security.handler.AjaxAuthenticationEntryPoint; |
| | | import kr.wisestone.owl.config.security.handler.AjaxAuthenticationFailureHandler; |
| | | import kr.wisestone.owl.config.security.handler.AjaxAuthenticationSuccessHandler; |
| | | import kr.wisestone.owl.config.security.handler.AjaxLogoutSuccessHandler; |
| | | import kr.wisestone.owl.config.security.service.UserSecurityService; |
| | | import kr.wisestone.owl.config.security.strategy.SecuritySessionExpiredStrategy; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.authentication.AuthenticationManager; |
| | | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; |
| | | import org.springframework.security.config.BeanIds; |
| | | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.builders.WebSecurity; |
| | | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
| | | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
| | | import org.springframework.security.core.session.SessionRegistry; |
| | | import org.springframework.security.crypto.factory.PasswordEncoderFactories; |
| | | import org.springframework.security.crypto.password.PasswordEncoder; |
| | | import org.springframework.security.web.session.ConcurrentSessionFilter; |
| | | import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices; |
| | | |
| | | @Configuration |
| | | @EnableWebSecurity |
| | | public class SecurityConfiguration extends WebSecurityConfigurerAdapter { |
| | | |
| | | private static final String REMEMBER_ME_KEY = "rememberMe"; |
| | | |
| | | @Autowired |
| | | private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler; |
| | | |
| | | @Autowired |
| | | private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler; |
| | | |
| | | @Autowired |
| | | private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler; |
| | | |
| | | @Autowired |
| | | private AjaxAuthenticationEntryPoint authenticationEntryPoint; |
| | | |
| | | @Autowired |
| | | private UserSecurityService userSecurityService; |
| | | |
| | | @Autowired |
| | | private SessionRegistry sessionRegistry; |
| | | |
| | | @Autowired |
| | | public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { |
| | | auth.userDetailsService(this.userSecurityService) |
| | | .passwordEncoder(this.passwordEncoder()); |
| | | } |
| | | |
| | | @Bean |
| | | public DaoAuthenticationProvider authenticationProvider() { |
| | | DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); |
| | | authenticationProvider.setUserDetailsService(this.userSecurityService); |
| | | authenticationProvider.setPasswordEncoder(this.passwordEncoder()); |
| | | return authenticationProvider; |
| | | } |
| | | |
| | | @Bean(name = BeanIds.AUTHENTICATION_MANAGER) |
| | | @Override |
| | | public AuthenticationManager authenticationManagerBean() throws Exception { |
| | | return super.authenticationManagerBean(); |
| | | } |
| | | |
| | | @Bean |
| | | public PasswordEncoder passwordEncoder() { |
| | | return PasswordEncoderFactories.createDelegatingPasswordEncoder(); |
| | | } |
| | | |
| | | @Bean |
| | | public AjaxSessionExpiredFilter ajaxSessionExpiredFilter() { |
| | | return new AjaxSessionExpiredFilter(this.sessionRegistry); |
| | | } |
| | | |
| | | @Bean |
| | | public SecuritySessionExpiredStrategy securitySessionExpiredStrategy() { |
| | | return new SecuritySessionExpiredStrategy(Constants.SESSION_EXPIRE_REDIRECT_URL); |
| | | } |
| | | |
| | | @Bean |
| | | public SpringSessionRememberMeServices springSessionRememberMeServices() { |
| | | SpringSessionRememberMeServices springSessionRememberMeServices = |
| | | new SpringSessionRememberMeServices(); |
| | | |
| | | springSessionRememberMeServices.setAlwaysRemember(false); |
| | | springSessionRememberMeServices.setRememberMeParameterName(REMEMBER_ME_KEY); |
| | | return springSessionRememberMeServices; |
| | | } |
| | | |
| | | @Override |
| | | public void configure(WebSecurity web) { |
| | | web.ignoring() |
| | | .antMatchers("/**/*.{js,css}"); |
| | | } |
| | | |
| | | @Override |
| | | protected void configure(HttpSecurity http) throws Exception { |
| | | http.formLogin() |
| | | .loginProcessingUrl("/security/login") |
| | | .successHandler(this.ajaxAuthenticationSuccessHandler) |
| | | .failureHandler(this.ajaxAuthenticationFailureHandler) |
| | | .usernameParameter("j_username") |
| | | .passwordParameter("j_password") |
| | | .permitAll(); |
| | | |
| | | http.logout() |
| | | .clearAuthentication(true) |
| | | .logoutUrl("/security/logout") |
| | | .logoutSuccessHandler(this.ajaxLogoutSuccessHandler) |
| | | .deleteCookies("JSESSIONID", REMEMBER_ME_KEY) |
| | | .invalidateHttpSession(true) |
| | | .permitAll(); |
| | | |
| | | http.headers() |
| | | .frameOptions() |
| | | .disable() |
| | | .and() |
| | | .csrf() |
| | | .disable() |
| | | .httpBasic() |
| | | .and() |
| | | .exceptionHandling() |
| | | .authenticationEntryPoint(this.authenticationEntryPoint); |
| | | |
| | | http.authorizeRequests() |
| | | .antMatchers("/kakaoOAuth2CallBack").permitAll() |
| | | .antMatchers("/naverOAuth2CallBack").permitAll() |
| | | .antMatchers("/googleOAuth2CallBack").permitAll() |
| | | .antMatchers("/facebookOAuth2CallBack").permitAll() |
| | | .antMatchers("/user/addSocialLogin").permitAll() |
| | | .antMatchers("/user/add").permitAll() |
| | | .antMatchers("/user/getUserSession").permitAll() |
| | | .antMatchers("/user/returnEmailPassword").permitAll() |
| | | .antMatchers("/workspace/find").permitAll() |
| | | .antMatchers("/workspace/findPrimaryWorkspace").permitAll() |
| | | .antMatchers("/guide/detail").permitAll() |
| | | .antMatchers("/language/change").permitAll() |
| | | .antMatchers("/security/*").permitAll() |
| | | .antMatchers("/**/*").authenticated(); |
| | | |
| | | |
| | | http.rememberMe() |
| | | .rememberMeServices(this.springSessionRememberMeServices()); |
| | | |
| | | |
| | | http.sessionManagement() |
| | | .maximumSessions(1) |
| | | .maxSessionsPreventsLogin(false) |
| | | .expiredSessionStrategy(this.securitySessionExpiredStrategy()) |
| | | .sessionRegistry(this.sessionRegistry).and().and() |
| | | .addFilterBefore(this.ajaxSessionExpiredFilter(), ConcurrentSessionFilter.class); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import kr.wisestone.owl.config.websocket.RedisSubscriber; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.data.redis.connection.RedisConnectionFactory; |
| | | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.data.redis.listener.ChannelTopic; |
| | | import org.springframework.data.redis.listener.RedisMessageListenerContainer; |
| | | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; |
| | | import org.springframework.data.redis.serializer.StringRedisSerializer; |
| | | import org.springframework.security.web.session.HttpSessionEventPublisher; |
| | | import org.springframework.session.data.redis.config.ConfigureRedisAction; |
| | | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; |
| | | import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; |
| | | |
| | | /** |
| | | * Created by jeong on 2019-02-28. |
| | | */ |
| | | @Configuration |
| | | @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) |
| | | public class SessionConfiguration extends AbstractHttpSessionApplicationInitializer { |
| | | @Value("${redis.host}") |
| | | private String redisHost; |
| | | |
| | | @Value("${redis.port}") |
| | | private int redisPort; |
| | | |
| | | @Value("${redis.common.topic}") |
| | | private String redisCommonTopic; |
| | | |
| | | @Bean |
| | | public RedisConnectionFactory redisConnectionFactory() { |
| | | return new LettuceConnectionFactory(this.redisHost, this.redisPort); |
| | | } |
| | | |
| | | @Bean |
| | | public HttpSessionEventPublisher httpSessionEventPublisher() { |
| | | return new HttpSessionEventPublisher(); |
| | | } |
| | | |
| | | @Bean |
| | | public ConfigureRedisAction configureRedisAction() { |
| | | return ConfigureRedisAction.NO_OP; |
| | | } |
| | | |
| | | @Bean |
| | | public RedisSubscriber redisSubscriber() { |
| | | return new RedisSubscriber(); |
| | | } |
| | | |
| | | @Bean |
| | | public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) { |
| | | RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); |
| | | redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); |
| | | redisMessageListenerContainer.addMessageListener(this.redisSubscriber(), new ChannelTopic(this.redisCommonTopic)); |
| | | return redisMessageListenerContainer; |
| | | } |
| | | |
| | | @Bean |
| | | public StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { |
| | | StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); |
| | | stringRedisTemplate.setConnectionFactory(redisConnectionFactory); |
| | | stringRedisTemplate.setKeySerializer(new StringRedisSerializer()); |
| | | stringRedisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(String.class)); |
| | | return stringRedisTemplate; |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import org.apache.commons.codec.CharEncoding; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.thymeleaf.spring5.SpringTemplateEngine; |
| | | import org.thymeleaf.templatemode.TemplateMode; |
| | | import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-19. |
| | | */ |
| | | @Configuration |
| | | public class ThymeleafConfiguration { |
| | | |
| | | @Bean |
| | | public ClassLoaderTemplateResolver emailTemplateResolver() { |
| | | ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver(); |
| | | emailTemplateResolver.setPrefix("mails/"); |
| | | emailTemplateResolver.setSuffix(".html"); |
| | | emailTemplateResolver.setTemplateMode(TemplateMode.HTML); |
| | | emailTemplateResolver.setCharacterEncoding(CharEncoding.UTF_8); |
| | | emailTemplateResolver.setOrder(1); |
| | | return emailTemplateResolver; |
| | | } |
| | | |
| | | @Bean |
| | | public SpringTemplateEngine templateEngine() { |
| | | SpringTemplateEngine templateEngine = new SpringTemplateEngine(); |
| | | templateEngine.addTemplateResolver(emailTemplateResolver()); |
| | | return templateEngine; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import kr.wisestone.owl.web.converter.FileHttpMessageConverter; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.converter.HttpMessageConverter; |
| | | import org.springframework.http.converter.StringHttpMessageConverter; |
| | | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; |
| | | import org.springframework.web.multipart.MultipartResolver; |
| | | import org.springframework.web.multipart.commons.CommonsMultipartResolver; |
| | | import org.springframework.web.servlet.LocaleResolver; |
| | | import org.springframework.web.servlet.config.annotation.*; |
| | | import org.springframework.web.servlet.i18n.CookieLocaleResolver; |
| | | import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Locale; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-08-01. |
| | | */ |
| | | @EnableWebMvc |
| | | @Configuration |
| | | public class WebMvcConfiguration implements WebMvcConfigurer { |
| | | |
| | | @Override |
| | | public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { |
| | | converters.add(new StringHttpMessageConverter()); |
| | | |
| | | MappingJackson2HttpMessageConverter jsonConverter = this.mappingJackson2HttpMessageConverter(); |
| | | jsonConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML)); |
| | | converters.add(jsonConverter); |
| | | |
| | | FileHttpMessageConverter fileConverter = this.fileHttpMessageConverter(); |
| | | converters.add(fileConverter); |
| | | } |
| | | |
| | | @Bean |
| | | public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { |
| | | return new MappingJackson2HttpMessageConverter(); |
| | | } |
| | | |
| | | @Bean |
| | | public FileHttpMessageConverter fileHttpMessageConverter() { |
| | | return new FileHttpMessageConverter(); |
| | | } |
| | | |
| | | @Bean |
| | | public MultipartResolver multipartResolver() { |
| | | CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); |
| | | commonsMultipartResolver.setMaxUploadSize(314572800); |
| | | return commonsMultipartResolver; |
| | | } |
| | | |
| | | @Bean |
| | | public LocaleChangeInterceptor localeChangeInterceptor() { |
| | | LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); |
| | | localeChangeInterceptor.setParamName("language"); |
| | | return localeChangeInterceptor; |
| | | } |
| | | |
| | | @Bean |
| | | public LocaleResolver localeResolver() { |
| | | CookieLocaleResolver localeResolver = new CookieLocaleResolver(); |
| | | localeResolver.setCookieMaxAge(3600); |
| | | localeResolver.setDefaultLocale(new Locale("ko_KR")); |
| | | Locale locale = new Locale("ko", "KR"); |
| | | locale.setDefault(locale); |
| | | |
| | | return localeResolver; |
| | | } |
| | | |
| | | @Override |
| | | public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { |
| | | configurer.enable(); |
| | | } |
| | | |
| | | @Override |
| | | public void addViewControllers(ViewControllerRegistry registry) { |
| | | registry.addViewController("/").setViewName("index.html"); |
| | | } |
| | | |
| | | @Override |
| | | public void addInterceptors(InterceptorRegistry registry) { |
| | | registry.addInterceptor(this.localeChangeInterceptor()); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import kr.wisestone.owl.config.websocket.WebSocketHandshakeHandler; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.messaging.simp.config.MessageBrokerRegistry; |
| | | import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; |
| | | import org.springframework.web.socket.config.annotation.StompEndpointRegistry; |
| | | import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; |
| | | import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; |
| | | |
| | | @Configuration |
| | | @EnableWebSocketMessageBroker |
| | | public class WebSocketStompConfiguration implements WebSocketMessageBrokerConfigurer { |
| | | |
| | | @Override |
| | | public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { |
| | | stompEndpointRegistry.addEndpoint("/owl-socket") |
| | | .setAllowedOrigins("*") |
| | | .addInterceptors(new HttpSessionHandshakeInterceptor()) |
| | | .setHandshakeHandler(new WebSocketHandshakeHandler()) |
| | | .withSockJS(); |
| | | } |
| | | |
| | | @Override |
| | | public void configureMessageBroker(MessageBrokerRegistry registry) { |
| | | registry.enableSimpleBroker("/session", "/notification", "/permission"); |
| | | registry.setApplicationDestinationPrefixes("/app"); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.kafka; |
| | | |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import org.apache.kafka.clients.consumer.ConsumerRecord; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.kafka.annotation.KafkaListener; |
| | | import org.springframework.messaging.simp.SimpMessagingTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class KafkaReceiver { |
| | | private static final Logger log = LoggerFactory.getLogger(KafkaReceiver.class); |
| | | |
| | | @Autowired |
| | | private SimpMessagingTemplate simpMessagingTemplate; |
| | | |
| | | @KafkaListener(topics = "#{'${kafka.common.topic}'}") |
| | | public void receive(ConsumerRecord<?, ?> consumerRecord) { |
| | | Map<String, Object> messageMap = (Map<String, Object>) consumerRecord.value(); |
| | | |
| | | CommonUtil.sendWebSocketMessage(this.simpMessagingTemplate, messageMap); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.kafka; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.kafka.core.KafkaTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class KafkaSender { |
| | | private static final Logger log = LoggerFactory.getLogger(KafkaSender.class); |
| | | |
| | | @Autowired |
| | | private KafkaTemplate<String, Object> kafkaTemplate; |
| | | |
| | | public void send(String topic, Map<String, Object> message) { |
| | | if(kafkaTemplate != null) |
| | | this.kafkaTemplate.send(topic, message); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.persistence.aop; |
| | | |
| | | import java.lang.reflect.Method; |
| | | |
| | | import org.aspectj.lang.ProceedingJoinPoint; |
| | | import org.aspectj.lang.annotation.Around; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.springframework.core.NamedThreadLocal; |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.transaction.TransactionDefinition; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.transaction.interceptor.TransactionAttributeSource; |
| | | |
| | | |
| | | @Aspect |
| | | public class TransactionDefinitionInterceptor implements Ordered { |
| | | |
| | | private static final ThreadLocal<TransactionDefinition> transactionDefinitionHolder = new NamedThreadLocal<>("Current aspect-driven transaction definition"); |
| | | |
| | | public static TransactionDefinition currentTransactionDefinition() { |
| | | return transactionDefinitionHolder.get(); |
| | | } |
| | | |
| | | public static boolean isCurrentTransactionReadOnly() { |
| | | return transactionDefinitionHolder.get() != null ? transactionDefinitionHolder.get().isReadOnly() : false; |
| | | } |
| | | |
| | | private final TransactionAttributeSource transactionAttributeSource; |
| | | |
| | | private int order = Ordered.LOWEST_PRECEDENCE - 10; |
| | | |
| | | public TransactionDefinitionInterceptor( |
| | | TransactionAttributeSource transactionAttributeSource) { |
| | | this.transactionAttributeSource = transactionAttributeSource; |
| | | } |
| | | |
| | | @Around("@annotation(transactional)") |
| | | public Object rememberTransactionDefinition( |
| | | ProceedingJoinPoint joinPoint, |
| | | Transactional transactional) throws Throwable { |
| | | Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); |
| | | Class<?> targetClass = joinPoint.getTarget().getClass(); |
| | | TransactionDefinition transactionDefinition = transactionAttributeSource.getTransactionAttribute(method, targetClass); |
| | | boolean restore = false; |
| | | if (transactionDefinitionHolder.get() == null) { |
| | | transactionDefinitionHolder.set(transactionDefinition); |
| | | restore = true; |
| | | } |
| | | try { |
| | | return joinPoint.proceed(); |
| | | } finally { |
| | | if (restore) { |
| | | transactionDefinitionHolder.set(null); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void setOrder(int order) { |
| | | this.order = order; |
| | | } |
| | | |
| | | @Override |
| | | public int getOrder() { |
| | | return order; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.persistence.routing; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.config.persistence.aop.TransactionDefinitionInterceptor; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | public class TransactionDefinitionRoutingDataSource extends AbstractRoutingDataSource { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | private List<Object> dataSourceKeys; |
| | | |
| | | private final AtomicInteger currentIndex = new AtomicInteger(); |
| | | |
| | | @Override |
| | | public void setTargetDataSources(Map<Object, Object> targetDataSources) { |
| | | super.setTargetDataSources(targetDataSources); |
| | | this.dataSourceKeys = Lists.newArrayList(targetDataSources.keySet()); |
| | | } |
| | | |
| | | @Override |
| | | protected Object determineCurrentLookupKey() { |
| | | if (TransactionDefinitionInterceptor |
| | | .isCurrentTransactionReadOnly() |
| | | && !dataSourceKeys.isEmpty()) { |
| | | int size = dataSourceKeys.size(); |
| | | Object key = dataSourceKeys.get(currentIndex.getAndIncrement() % size); |
| | | return key; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.exception; |
| | | |
| | | import org.springframework.security.core.AuthenticationException; |
| | | |
| | | public class LoginProcessingException extends AuthenticationException { |
| | | |
| | | public LoginProcessingException(String message) { |
| | | super(message); |
| | | } |
| | | |
| | | public LoginProcessingException(String message, Throwable t) { |
| | | super(message, t); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.filter; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import org.apache.commons.io.FilenameUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.security.core.session.SessionInformation; |
| | | import org.springframework.security.core.session.SessionRegistry; |
| | | import org.springframework.security.web.DefaultRedirectStrategy; |
| | | import org.springframework.security.web.RedirectStrategy; |
| | | import org.springframework.security.web.authentication.logout.LogoutHandler; |
| | | import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; |
| | | import org.springframework.security.web.util.UrlUtils; |
| | | import org.springframework.util.Assert; |
| | | import org.springframework.web.filter.GenericFilterBean; |
| | | |
| | | import javax.servlet.FilterChain; |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.ServletRequest; |
| | | import javax.servlet.ServletResponse; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.servlet.http.HttpSession; |
| | | import java.io.IOException; |
| | | |
| | | public class AjaxSessionExpiredFilter extends GenericFilterBean { |
| | | private final Logger log = LoggerFactory.getLogger(AjaxSessionExpiredFilter.class); |
| | | |
| | | private String ajaxHeader; |
| | | private SessionRegistry sessionRegistry; |
| | | private String expiredUrl; |
| | | private LogoutHandler[] handlers = new LogoutHandler[]{new SecurityContextLogoutHandler()}; |
| | | private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); |
| | | |
| | | public void destroy() { |
| | | } |
| | | |
| | | public AjaxSessionExpiredFilter(SessionRegistry sessionRegistry) { |
| | | Assert.notNull(sessionRegistry, "SessionRegistry required"); |
| | | this.sessionRegistry = sessionRegistry; |
| | | } |
| | | |
| | | public AjaxSessionExpiredFilter(SessionRegistry sessionRegistry, String expiredUrl) { |
| | | Assert.notNull(sessionRegistry, "SessionRegistry required"); |
| | | Assert.isTrue(expiredUrl == null || UrlUtils.isValidRedirectUrl(expiredUrl), expiredUrl + " isn\'t a valid redirect URL"); |
| | | this.sessionRegistry = sessionRegistry; |
| | | this.expiredUrl = expiredUrl; |
| | | } |
| | | |
| | | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { |
| | | HttpServletRequest request = (HttpServletRequest)req; |
| | | HttpServletResponse response = (HttpServletResponse)res; |
| | | HttpSession session = request.getSession(false); |
| | | |
| | | String uri = request.getRequestURI(); |
| | | if (FilenameUtils.isExtension(uri, "html") || uri.contains("/user/getUserSession") || uri.contains("/owl-socket")) { |
| | | chain.doFilter(request, response); |
| | | return; |
| | | } |
| | | |
| | | if(session != null) { |
| | | SessionInformation info = this.sessionRegistry.getSessionInformation(session.getId()); |
| | | if(info != null) { |
| | | if(info.isExpired()) { |
| | | this.doLogoutAndFireErrorMessage(request, response); |
| | | return; |
| | | } |
| | | |
| | | this.sessionRegistry.refreshLastRequest(info.getSessionId()); |
| | | } |
| | | } |
| | | |
| | | chain.doFilter(request, response); |
| | | } |
| | | |
| | | private void doLogoutAndFireErrorMessage(HttpServletRequest request, HttpServletResponse response) throws IOException { |
| | | this.doLogout(request, response); |
| | | response.sendRedirect(Constants.SESSION_EXPIRE_REDIRECT_URL); |
| | | } |
| | | |
| | | private void doLogout(HttpServletRequest request, HttpServletResponse response) { |
| | | Authentication auth = SecurityContextHolder.getContext().getAuthentication(); |
| | | LogoutHandler[] var4 = this.handlers; |
| | | int var5 = var4.length; |
| | | |
| | | for(int var6 = 0; var6 < var5; ++var6) { |
| | | LogoutHandler handler = var4[var6]; |
| | | handler.logout(request, response, auth); |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.handler; |
| | | |
| | | import kr.wisestone.owl.common.MessageAccessor; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.core.AuthenticationException; |
| | | import org.springframework.security.web.AuthenticationEntryPoint; |
| | | import org.springframework.stereotype.Component; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.io.PrintWriter; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Component |
| | | public class AjaxAuthenticationEntryPoint implements AuthenticationEntryPoint { |
| | | |
| | | private final Logger log = LoggerFactory.getLogger(AjaxAuthenticationEntryPoint.class); |
| | | |
| | | @Autowired |
| | | protected MessageAccessor messageAccessor; |
| | | |
| | | @Override |
| | | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) { |
| | | Map<String, Object> resJsonData = new HashMap<>(); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_MESSAGE, |
| | | this.messageAccessor.getResMessage(MsgConstants.SESSION_EXPIRED, Constants.RES_KEY_MSG_FAIL)); |
| | | |
| | | response.setContentType("application/json"); |
| | | response.setCharacterEncoding("utf-8"); |
| | | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); |
| | | |
| | | String data = ConvertUtil.convertObjectToJson(resJsonData); |
| | | |
| | | try (PrintWriter out = response.getWriter()) { |
| | | out.print(data); |
| | | out.flush(); |
| | | } catch (IOException e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.handler; |
| | | |
| | | import kr.wisestone.owl.common.MessageAccessor; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.authentication.BadCredentialsException; |
| | | import org.springframework.security.core.AuthenticationException; |
| | | import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.io.PrintWriter; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Component |
| | | public class AjaxAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { |
| | | |
| | | private final Logger log = LoggerFactory.getLogger(AjaxAuthenticationFailureHandler.class); |
| | | |
| | | @Autowired |
| | | protected MessageAccessor messageAccessor; |
| | | |
| | | @Override |
| | | public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) { |
| | | |
| | | Map<String, Object> resJsonData = new HashMap<>(); |
| | | |
| | | if (exception instanceof BadCredentialsException) { |
| | | resJsonData.put(Constants.RES_KEY_MESSAGE, this.messageAccessor.getResMessage(MsgConstants.USER_NOT_EQUAL_PASSWORD, Constants.RES_KEY_MSG_FAIL)); |
| | | } |
| | | else { |
| | | resJsonData.put(Constants.RES_KEY_MESSAGE, this.messageAccessor.getResMessage(exception.getMessage(), Constants.RES_KEY_MSG_FAIL)); |
| | | } |
| | | |
| | | response.setContentType("application/json"); |
| | | response.setCharacterEncoding("utf-8"); |
| | | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); |
| | | |
| | | String data = ConvertUtil.convertObjectToJson(resJsonData); |
| | | |
| | | try { |
| | | PrintWriter out = response.getWriter(); |
| | | out.print(data); |
| | | out.flush(); |
| | | } catch (IOException e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.handler; |
| | | |
| | | import kr.wisestone.owl.common.MessageAccessor; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.ElasticSearchUtil; |
| | | import kr.wisestone.owl.vo.UserVo; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; |
| | | import org.springframework.stereotype.Component; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.io.PrintWriter; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Component |
| | | public class AjaxAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { |
| | | |
| | | private final Logger log = LoggerFactory.getLogger(AjaxAuthenticationSuccessHandler.class); |
| | | |
| | | @Autowired |
| | | protected MessageAccessor messageAccessor; |
| | | |
| | | @Override |
| | | public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication) { |
| | | |
| | | Map<String, Object> resJsonData = new HashMap<>(); |
| | | User user = (User) authentication.getPrincipal(); |
| | | try { |
| | | log.info(ElasticSearchUtil.makeUserSessionHistoryMessage(httpServletRequest, ConvertUtil.copyProperties(user, UserVo.class))); |
| | | } |
| | | catch (Exception ex) { |
| | | log.error(ex.getMessage()); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_MESSAGE, |
| | | this.messageAccessor.getResMessage(MsgConstants.SUCCESS_REQUEST, Constants.RES_KEY_MSG_SUCCESS)); |
| | | |
| | | response.setContentType("application/json"); |
| | | response.setCharacterEncoding("utf-8"); |
| | | response.setStatus(HttpServletResponse.SC_OK); |
| | | |
| | | String data = ConvertUtil.convertObjectToJson(resJsonData); |
| | | |
| | | try { |
| | | PrintWriter out = response.getWriter(); |
| | | out.print(data); |
| | | out.flush(); |
| | | } catch (IOException e) { |
| | | log.error(e.getMessage()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.handler; |
| | | |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler; |
| | | import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | @Component |
| | | public class AjaxLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler { |
| | | |
| | | @Override |
| | | public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { |
| | | response.setStatus(HttpServletResponse.SC_OK); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.service; |
| | | |
| | | import kr.wisestone.owl.common.MessageAccessor; |
| | | import kr.wisestone.owl.config.security.exception.LoginProcessingException; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.core.userdetails.UserDetails; |
| | | import org.springframework.security.core.userdetails.UserDetailsService; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component("userSecurityService") |
| | | public class UserSecurityService implements UserDetailsService { |
| | | |
| | | @Autowired |
| | | protected MessageAccessor messageAccessor; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Override |
| | | public UserDetails loadUserByUsername(final String login) { |
| | | User user = this.userService.findByAccount(login); |
| | | |
| | | if (user == null) { |
| | | throw new LoginProcessingException(MsgConstants.USER_NOT_EXIST); |
| | | } |
| | | |
| | | if (!User.USER_STATUS_ACTIVE.equals(user.getStatus())) { |
| | | throw new LoginProcessingException(MsgConstants.USER_NOT_USE_ACTIVE_STATUS); |
| | | } |
| | | |
| | | return user; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.security.strategy; |
| | | |
| | | import org.springframework.security.web.session.SessionInformationExpiredEvent; |
| | | import org.springframework.security.web.session.SessionInformationExpiredStrategy; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | public class SecuritySessionExpiredStrategy implements SessionInformationExpiredStrategy { |
| | | |
| | | private String defaultUrl; |
| | | |
| | | public SecuritySessionExpiredStrategy(String defaultUrl) { |
| | | this.defaultUrl = defaultUrl; |
| | | } |
| | | |
| | | @Override |
| | | public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException { |
| | | HttpServletResponse response = event.getResponse(); |
| | | response.sendRedirect(this.defaultUrl); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.websocket; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.data.redis.listener.ChannelTopic; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class RedisPublisher { |
| | | |
| | | @Autowired |
| | | private RedisTemplate redisTemplate; |
| | | |
| | | public void publish(ChannelTopic channelTopic, Map<String, Object> message) { |
| | | this.redisTemplate.convertAndSend(channelTopic.getTopic(), message); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.websocket; |
| | | |
| | | import com.google.gson.Gson; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.connection.Message; |
| | | import org.springframework.data.redis.connection.MessageListener; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.messaging.simp.SimpMessagingTemplate; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public class RedisSubscriber implements MessageListener { |
| | | |
| | | @Autowired |
| | | private RedisTemplate redisTemplate; |
| | | |
| | | @Autowired |
| | | private SimpMessagingTemplate simpMessagingTemplate; |
| | | |
| | | @Override |
| | | public void onMessage(Message message, byte[] pattern) { |
| | | try { |
| | | Gson gson = new Gson(); |
| | | String publishMessage = (String) this.redisTemplate.getStringSerializer().deserialize(message.getBody()); |
| | | Map<String, Object> messageMap = (Map<String, Object>) gson.fromJson(publishMessage, Object.class); |
| | | |
| | | CommonUtil.sendWebSocketMessage(this.simpMessagingTemplate, messageMap); |
| | | |
| | | } catch (Exception ex) { |
| | | System.out.println("ex : " + ex.getMessage()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.websocket; |
| | | |
| | | import org.springframework.http.server.ServerHttpRequest; |
| | | import org.springframework.web.socket.WebSocketHandler; |
| | | import org.springframework.web.socket.server.support.DefaultHandshakeHandler; |
| | | |
| | | import java.security.Principal; |
| | | import java.util.Map; |
| | | |
| | | public class WebSocketHandshakeHandler extends DefaultHandshakeHandler { |
| | | |
| | | @Override |
| | | protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) { |
| | | return request.getPrincipal(); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.config.websocket; |
| | | |
| | | import com.google.gson.Gson; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.data.redis.listener.ChannelTopic; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class WebSocketService { |
| | | |
| | | @Autowired |
| | | private StringRedisTemplate stringRedisTemplate; |
| | | |
| | | @Autowired |
| | | private RedisPublisher redisPublisher; |
| | | |
| | | @Value("${redis.common.topic}") |
| | | private String redisCommonTopic; |
| | | |
| | | public void checkActiveUser() { |
| | | Map<String, Object> totalActiveUserMap = this.checkExpireWebSocketSession(); |
| | | Gson gson = new Gson(); |
| | | Map<String, Object> responseMap = new HashMap<>(); |
| | | |
| | | responseMap.put("url", "/session/user-list"); |
| | | responseMap.put("message", gson.toJson(totalActiveUserMap)); |
| | | ChannelTopic channelTopic = new ChannelTopic(this.redisCommonTopic); |
| | | |
| | | this.redisPublisher.publish(channelTopic, responseMap); |
| | | } |
| | | |
| | | private Map<String, Object> checkExpireWebSocketSession() { |
| | | Map<String, Object> totalActiveUserMap = new HashMap<>(); |
| | | Gson gson = new Gson(); |
| | | String loginUsers = this.stringRedisTemplate.opsForValue().get("activeUsers"); |
| | | |
| | | if (!StringUtils.isEmpty(loginUsers)) { |
| | | totalActiveUserMap = (Map<String, Object>)gson.fromJson(loginUsers, Object.class); |
| | | |
| | | Iterator<String> iterator = totalActiveUserMap.keySet().iterator(); |
| | | |
| | | while (iterator.hasNext()) { |
| | | String key = iterator.next(); |
| | | Map<String, Object> userMap = (Map<String, Object>)totalActiveUserMap.get(key); |
| | | |
| | | Long sessionActiveTime = Long.valueOf(MapUtil.getString(userMap, "sessionActiveTime")); |
| | | |
| | | if (System.currentTimeMillis() - sessionActiveTime >= 60000) { |
| | | iterator.remove(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return totalActiveUserMap; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.constant; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-08-14. |
| | | */ |
| | | public class Constants { |
| | | public static final String REQ_KEY_PAGE_VO = "page"; |
| | | public static final String REQ_KEY_CONTENT = "content"; |
| | | public static final String RES_KEY_MESSAGE = "message"; |
| | | public static final String RES_KEY_MSG_FAIL = "fail"; |
| | | public static final String RES_KEY_MSG_SUCCESS = "success"; |
| | | public static final String RES_KEY_CONTENTS = "data"; |
| | | public static final String SESSION_ACCOUNT = "account"; |
| | | public static final String EXCEL = "excel"; |
| | | public static final String SESSION_EXPIRE_REDIRECT_URL = "/#/login"; |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.constant; |
| | | |
| | | public class ElasticSearchConstants { |
| | | public static final String ISSUE_ADD = "ISSUE_ADD"; // 이슈 생성 |
| | | public static final String ISSUE_MODIFY = "ISSUE_MODIFY"; // 이슈 수정 |
| | | public static final String ISSUE_REMOVE = "ISSUE_REMOVE"; // 이슈 삭제 |
| | | public static final String ISSUE_FIND = "ISSUE_FIND"; // 이슈 조회 |
| | | public static final String ISSUE_DETAIL = "ISSUE_DETAIL"; // 이슈 상세 조회 |
| | | public static final String ISSUE_STATUS_CHANGE = "ISSUE_STATUS_CHANGE"; // 이슈 상태 변경 |
| | | public static final String ISSUE_USER_CHANGE = "ISSUE_STATUS_CHANGE"; // 이슈 담당자 변경 |
| | | public static final String ISSUE_ANOTHER_USER_SEND_EMAIL = "ISSUE_ANOTHER_USER_SEND_EMAIL"; // 다른 사용자에게 메일 보내기 |
| | | public static final String ISSUE_HISTORY_FIND = "ISSUE_HISTORY_FIND"; // 이슈 이력 조회 |
| | | public static final String ISSUE_RESERVATION = "ISSUE_RESERVATION"; // 이슈 예약 발생 |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.constant; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-14. |
| | | */ |
| | | public enum MailConstants { |
| | | WORKSPACE_JOIN("workspace.join.title", "workspaceJoinEmail"), // 회원 가입 |
| | | USER_SEARCH_PASSWORD("user.search.password.title", "userSearchPasswordEmail"), // 사용자 비밀번호 찾기 |
| | | USER_WITH_DRAW("user.withDraw.title", "userWithDrawEmail"), // 회원 탈퇴 |
| | | REGULAR_PAYMENT("regular.payment.title", "regularPaymentEmail"), // 정기 결제 완료 |
| | | REGULAR_PAYMENT_CANCEL("regular.payment.cancel.title", "regularPaymentCancelEmail"), // 정기 결제 취소 |
| | | REGULAR_PAYMENT_CANCEL_BY_ACCOUNTING_MANAGER("regular.payment.cancel.accounting.manager.title", "regularPaymentCancelByAccountingManagerEmail"), // 정기 결제 취소 |
| | | REGULAR_PAYMENT_MODIFY("regular.payment.modify.title", "regularPaymentModifyEmail"), // 정기 결제 변경 |
| | | WORKSPACE_INVITE_NEW_USER("workspace.inviteNewUser.title", "workspaceInviteNewUserEmail"), // 신규 사용자 업무 공간 초대 |
| | | WORKSPACE_MAX_USER_EXCESS("workspace.maxUserExcess.title", "workspaceMaxUserExcessEmail"), // 업무 공간 활성 사용자 초과 |
| | | USER_JOIN_STATISTICS("user.join.statistics.title", "userJoinStatisticsEmail"), // 사용자 현황 정보 |
| | | TOTAL_STATISTICS("total.statistics.title", "totalStatisticsEmail"), // 전체 시스템 현황 정보 |
| | | WORKSPACE_EXPIRE("workspace.expire.title", "workspaceExpireEmail"), // 업무 공간 사용 기간 만료 |
| | | WORKSPACE_EXPIRE_ALARM("workspace.expire.alarm.title", "workspaceExpireAlarmEmail"), // 업무 공간 사용 기간 만료 예정 안내 |
| | | |
| | | |
| | | WORKSPACE_MAX_STORAGE_EXCESS("workspace.maxStorageExcess.title", "workspaceMaxStorageExcessEmail"), // 업무 공간 저장 용량 초과 |
| | | WORKSPACE_INVITE_SYSTEM_USER("workspace.inviteSystemUser.title", "workspaceInviteSystemUserEmail"), // 기존 사용자 업무 공간 초대 |
| | | PROJECT_DEFAULT_EXCLUDE("project.default.exclude.title", "projectDefaultExcludeEmail"), // 프로젝트 일반 참여자 제외 |
| | | PROJECT_DEFAULT_INCLUDE("project.default.include.title", "projectDefaultIncludeEmail"), // 프로젝트 일반 참여자 참여 |
| | | PROJECT_MANAGER_EXCLUDE("project.manager.exclude.title", "projectManagerExcludeEmail"), // 프로젝트 관리자 제외 |
| | | PROJECT_MANAGER_INCLUDE("project.manager.include.title", "projectManagerIncludeEmail"), // 프로젝트 관리자 참여 |
| | | PROJECT_MANAGER_EXCLUDE_AND_PROJECT_DEFAULT_INCLUDE("project.manager.exclude.default.include.title", "projectManagerExcludeAndDefaultIncludeEmail"), // 프로젝트 관리자 제외 후 일반 사용자로 참여 |
| | | PROJECT_DEFAULT_EXCLUDE_AND_PROJECT_MANAGER_INCLUDE("project.default.exclude.manager.include.title", "projectDefaultExcludeAndManagerIncludeEmail"), // 일반 사용자에서 제외 후 프로젝트 관리자로 참여 |
| | | |
| | | ISSUE_ADD("issue.add.title", "issueAddEmail"), // 이슈 생성 |
| | | ISSUE_REMOVE("issue.remove.title", "issueRemoveEmail"), // 이슈 삭제 |
| | | ISSUE_SEND("issue.send.title", "issueSendEmail"); // 이슈 이메일 전달 |
| | | // ISSUE_MODIFY("issue.modify.title", "issueModifyEmail"); // 이슈 수정 |
| | | |
| | | |
| | | |
| | | private String title; |
| | | private String mailTemplate; |
| | | |
| | | MailConstants(String title, String mailTemplate) { |
| | | this.title = title; |
| | | this.mailTemplate = mailTemplate; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getMailTemplate() { |
| | | return mailTemplate; |
| | | } |
| | | |
| | | public void setMailTemplate(String mailTemplate) { |
| | | this.mailTemplate = mailTemplate; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.constant; |
| | | |
| | | /** |
| | | * Created by zenith at 20200803 |
| | | */ |
| | | public class MngPermission { |
| | | |
| | | public static final int USER_PERMISSION_MNG_WORKSPACE = 4096; // WORK SPACE 관리 1000000000000 |
| | | public static final int USER_PERMISSION_MNG_PROJECT = 2048; // 프로젝트 관리 0100000000000 |
| | | public static final int USER_PERMISSION_MNG_USER = 1024; // USER 관리 0010000000000 |
| | | public static final int USER_PERMISSION_MNG_ISSUE_STATUS = 512; // ISSUE SETTING 관리 0001000000000 |
| | | public static final int USER_PERMISSION_MNG_WORKFLOW = 256; // WORK FLOW 관리 0000100000000 |
| | | public static final int USER_PERMISSION_MNG_CUSTOME_FIELD = 128; // 사용자정의 필드 관리 0000010000000 |
| | | public static final int USER_PERMISSION_MNG_ISSUE_TYPE = 64; // ISSUE TYPE 관리 0000000100000 |
| | | public static final int USER_PERMISSION_MNG_NOTICE = 32; // ISSUE TYPE 관리 0000000010000 |
| | | public static final int USER_PERMISSION_MNG_FAQ = 16; // FAQ 관리 0000000001000 |
| | | public static final int USER_PERMISSION_MNG_QNA = 8; // 공지사항 관리 0000000000100 |
| | | public static final int USER_PERMISSION_MNG_EVENT = 4; // 공지사항 관리 0000000000010 |
| | | public static final int USER_PERMISSION_MNG_GUIDE = 2; // 사용자 알림 관리 0000000000001 |
| | | public static final int USER_PERMISSION_MNG_NONE = 0; // |
| | | |
| | | public static final int USER_PERMISSION_MNG_ISSUE_SETTING = (USER_PERMISSION_MNG_ISSUE_STATUS | USER_PERMISSION_MNG_WORKFLOW | |
| | | USER_PERMISSION_MNG_CUSTOME_FIELD | USER_PERMISSION_MNG_ISSUE_TYPE); |
| | | |
| | | public static boolean checkMngPermission(int userPermission, int typePermission) |
| | | { |
| | | return ((userPermission & typePermission) != 0); |
| | | } |
| | | |
| | | public static int makePermission(boolean userPermission, int typePermission) |
| | | { |
| | | if(userPermission) |
| | | return typePermission; |
| | | else |
| | | return USER_PERMISSION_MNG_NONE; |
| | | } |
| | | |
| | | public static int makeAllPermission() |
| | | { |
| | | int nPermission = (USER_PERMISSION_MNG_WORKSPACE | |
| | | USER_PERMISSION_MNG_PROJECT | |
| | | USER_PERMISSION_MNG_USER | |
| | | USER_PERMISSION_MNG_NOTICE | |
| | | USER_PERMISSION_MNG_FAQ | |
| | | USER_PERMISSION_MNG_QNA | |
| | | USER_PERMISSION_MNG_EVENT | |
| | | USER_PERMISSION_MNG_GUIDE | |
| | | USER_PERMISSION_MNG_ISSUE_SETTING); |
| | | |
| | | return nPermission; |
| | | } |
| | | |
| | | public static int makeSubAllPermission() |
| | | { |
| | | int nPermission = (/*USER_PERMISSION_MNG_WORKSPACE |*/ |
| | | USER_PERMISSION_MNG_USER | USER_PERMISSION_MNG_NOTICE | |
| | | USER_PERMISSION_MNG_FAQ | USER_PERMISSION_MNG_QNA | |
| | | USER_PERMISSION_MNG_EVENT | USER_PERMISSION_MNG_GUIDE | |
| | | USER_PERMISSION_MNG_ISSUE_SETTING); |
| | | |
| | | return nPermission; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.constant; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-08-02. |
| | | */ |
| | | public class MsgConstants { |
| | | |
| | | public static final String PROJECT_NAME_MAX_LENGTH_OUT = "PROJECT_NAME_MAX_LENGTH_OUT"; // 프로젝트 명은 최대 50글자까지 입력할 수 있습니다. |
| | | public static final String DATE_PICKER_NOT_AVAILABLE = "DATE_PICKER_NOT_AVAILABLE"; // 날짜 선택이 잘못되었습니다. |
| | | public static final String PROJECT_NOT_EXIST = "PROJECT_NOT_EXIST"; // 프로젝트가 존재하지 않습니다. |
| | | public static final String PROJECT_NOT_MANAGER = "PROJECT_NOT_MANAGER"; // 프로젝트 관리자가 존재하지 않습니다. |
| | | public static final String PROJECT_NOT_MODIFY_PERMISSION = "PROJECT_NOT_MODIFY_PERMISSION"; // 프로젝트 관리 권한이 없습니다. |
| | | public static final String PROJECT_NOT_NAME = "PROJECT_NOT_NAME"; // 프로젝트 이름이 입력되지 않았습니다. |
| | | public static final String PROJECT_NOT_STATUS = "PROJECT_NOT_STATUS"; // 프로젝트의 상태가 선택되지 않았습니다. |
| | | public static final String DATE_NOT_EXIST = "DATE_NOT_EXIST"; // 날짜가 선택되지 않았습니다. |
| | | public static final String PROJECT_OVER_LENGTH_PROJECT_KEY = "PROJECT_OVER_LENGTH_PROJECT_KEY"; // 프로젝트 키는 최대 10글자만 입력 가능합니다. |
| | | public static final String PROJECT_KEY_NOT_EXIST = "PROJECT_KEY_NOT_EXIST"; // 프로젝트 키가 입력 되지 않았습니다. |
| | | public static final String PROJECT_USED_NAME = "PROJECT_USED_NAME"; // 프로젝트 이름이 이미 사용되고 있습니다. |
| | | public static final String DEFAULT_PROJECT_NOT_REMOVE = "DEFAULT_PROJECT_NOT_REMOVE"; // 기본으로 제공되는 프로젝트는 삭제할 수 없습니다. |
| | | public static final String PROJECT_REMOVE_NOT_SELECT = "PROJECT_REMOVE_NOT_SELECT"; // 삭제할 프로젝트가 선택되지 않았습니다. |
| | | public static final String PROJECT_NOT_INCLUDE_USER = "PROJECT_NOT_INCLUDE_USER"; // 프로젝트에 참여하고 있지 않은 사용자 입니다. |
| | | public static final String PROJECT_USED_PROJECT_KEY = "PROJECT_USED_PROJECT_KEY"; // 프로젝트 키가 이미 사용되고 있습니다. |
| | | |
| | | public static final String PAYMENT_NOT_EXIST = "PAYMENT_NOT_EXIST"; // 결제 정보가 없습니다. |
| | | public static final String PAYMENT_EXECUTE_ONLY_WORKSPACE_MANAGER = "PAYMENT_EXECUTE_ONLY_WORKSPACE_MANAGER"; // 결제는 업무 공간 관리자만 할 수 있습니다. |
| | | public static final String PAYMENT_BUY_USER_MUST_BE_GREATER_THAN_ZERO = "PAYMENT_BUY_USER_MUST_BE_GREATER_THAN_ZERO"; // 결제하려는 사용자 수는 0보다 커야 합니다. |
| | | public static final String PAYMENT_NO_TYPE = "PAYMENT_NO_TYPE"; // 결제 유형이 입력되지 않았습니다. |
| | | public static final String PAYMENT_HISTORY_NOT_EXIST = "PAYMENT_HISTORY_NOT_EXIST"; // 결제 이력 정보가 없습니다. |
| | | |
| | | public static final String USER_WORKSPACE_MANAGER_NOT_EXIST = "USER_WORKSPACE_MANAGER_NOT_EXIST"; // 업무 공간 관리자 정보가 존재하지 않습니다. |
| | | public static final String OAUTH_STATE_VALUE_NOT_EQUAL = "OAUTH_STATE_VALUE_NOT_EQUAL"; // OAuth 인증에 실패했습니다. - 상태가 틀렸는데 굳이 알려줄 필요는 없다. |
| | | public static final String WORKSPACE_NOT_EXIST = "WORKSPACE_NOT_EXIST"; // 업무 공간이 존재하지 않습니다. |
| | | public static final String WORKSPACE_STORAGE_SIZE_EXCESS = "WORKSPACE_STORAGE_SIZE_EXCESS"; // 업무 공간 저장 공간이 초과되었습니다. 불필요한 파일을 정리하세요. |
| | | public static final String WORKSPACE_MANAGER_NOT_CHANGE_USE_YN = "WORKSPACE_MANAGER_NOT_CHANGE_USE_YN"; // 업무 공간 관리자는 비활성화로 변경 될 수 없습니다. |
| | | public static final String WORKSPACE_PERIOD_REMAIN = "WORKSPACE_PERIOD_REMAIN"; // 업무 공간 사용 기간이 남아 있습니다. |
| | | public static final String WORKSPACE_USE_PERIOD_EXCESS = "WORKSPACE_USE_PERIOD_EXCESS"; // 업무 공간 사용 기간이 종료되어 생성, 수정, 삭제 기능을 사용할 수 없습니다. |
| | | public static final String WORKSPACE_INCLUDE_DISABLED = "WORKSPACE_INCLUDE_DISABLED"; // 해당 업무 공간에서 비활성 상태이므로 생성, 수정, 삭제 기능을 사용할 수 없습니다. |
| | | |
| | | public static final String ATTACHED_FILE_NOT_EXIST = "ATTACHED_FILE_NOT_EXIST"; // 첨부 파일 정보를 찾을 수 없습니다. |
| | | |
| | | public static final String START_ISSUE_STATUS_NOT_EXIST = "START_ISSUE_STATUS_NOT_EXIST"; // 시작하는 이슈 상태가 존재하지 않습니다. |
| | | public static final String END_ISSUE_STATUS_NOT_EXIST = "END_ISSUE_STATUS_NOT_EXIST"; // 종료하는 이슈 상태가 존재하지 않습니다. |
| | | |
| | | public static final String EMAIL_NOT_SEND = "EMAIL_NOT_SEND"; // 메일을 전송할 수 없습니다. |
| | | public static final String INVITE_USER_USED_WORKSPACE = "INVITE_USER_USED_WORKSPACE"; // 해당 사용자는 이미 업무 공간에 참여하고 있습니다. |
| | | |
| | | public static final String PROJECT_ROLE_NOT_EXIST = "PROJECT_ROLE_NOT_EXIST"; // 프로젝트 역할이 존재하지 않습니다. |
| | | public static final String WORKSPACE_NOT_NAME = "WORKSPACE_NOT_NAME"; // 업무 공간 명이 입력되지 않았습니다. |
| | | public static final String WORKSPACE_MAX_USER_EXCESS = "WORKSPACE_MAX_USER_EXCESS"; // 업무 공간의 최대 사용자 수가 초과되었습니다. 최대 사용자 수가 초과되면 초대받은 사용자가 해당 업무 공간를 접근할 수 없습니다. |
| | | public static final String WORKSPACE_MAX_USER_EXCESS_NOT_INCLUDE = "WORKSPACE_MAX_USER_EXCESS_NOT_INCLUDE"; // 업무 공간의 최대 사용자 수가 초과되어 참여 상태로 변경할 수 없습니다. |
| | | public static final String WORKSPACE_OUT = "WORKSPACE_OUT"; // 참여하는 업무 공간에서 제외되었습니다. (1) |
| | | public static final String WORKSPACE_NAME_MAX_LENGTH_OUT = "WORKSPACE_NAME_MAX_LENGTH_OUT"; // 업무 공간 명은 최대 50글자까지 입력할 수 있습니다. |
| | | |
| | | public static final String DEFAULT_PROJECT_MANAGER_NOT_CHANGE = "DEFAULT_PROJECT_MANAGER_NOT_CHANGE"; // 기본 제공되는 프로젝트의 관리자는 업무 공간 관리자가 있어야 합니다. |
| | | |
| | | |
| | | public static final String ISSUE_STATUS_NAME_MAX_LENGTH_OUT = "ISSUE_STATUS_NAME_MAX_LENGTH_OUT"; // 이슈 상태명은 최대 50글자까지 입력할 수 있습니다. |
| | | public static final String ISSUE_STATUS_NOT_NAME = "ISSUE_STATUS_NOT_NAME"; // 이슈 상태 명이 입력되지 않았습니다. |
| | | public static final String ISSUE_STATUS_NOT_COLOR = "ISSUE_STATUS_NOT_COLOR"; // 이슈 상태의 색상이 입력되지 않았습니다. |
| | | public static final String ISSUE_STATUS_USED_NAME = "ISSUE_STATUS_USED_NAME"; // 이슈 상태 이름이 이미 사용되고 있습니다. |
| | | public static final String ISSUE_STATUS_REMOVE_NOT_SELECT = "ISSUE_STATUS_REMOVE_NOT_SELECT"; // 삭제할 이슈 상태가 선택되지 않았습니다. |
| | | public static final String DEFAULT_ISSUE_STATUS_NOT_REMOVE = "DEFAULT_ISSUE_STATUS_NOT_REMOVE"; // 기본으로 제공되는 이슈 상태는 삭제할 수 없습니다. |
| | | public static final String ISSUE_STATUS_NOT_EXIST = "ISSUE_STATUS_NOT_EXIST"; // 이슈 상태가 존재하지 않습니다. |
| | | public static final String READY_ISSUE_STATUS_NOT_EXIST = "READY_ISSUE_STATUS_NOT_EXIST"; // 이슈 상태 유형이 대기인 이슈 상태를 찾을 수 없습니다. |
| | | public static final String ISSUE_STATUS_CHANGE_NOT_TARGET = "ISSUE_STATUS_CHANGE_NOT_TARGET"; // 선택한 이슈 상태로 변경할 수 없습니다. 워크플로우를 확인하세요. |
| | | public static final String ISSUE_STATUS_USE_ISSUES = "ISSUE_STATUS_USE_ISSUES"; // 이슈 상태를 사용하고 있는 이슈가 존재하고 있습니다. |
| | | public static final String ISSUE_STATUS_USE_WORKFLOW = "ISSUE_STATUS_USE_WORKFLOW"; // 이슈 상태를 사용하고 있는 워크플로우가 존재하고 있습니다. |
| | | |
| | | public static final String WORKFLOW_NOT_EXIST = "WORKFLOW_NOT_EXIST"; // 워크플로우가 존재하지 않습니다. |
| | | public static final String WORKFLOW_NOT_NAME = "WORKFLOW_NOT_NAME"; // 워크플로우 명이 입력되지 않았습니다. |
| | | public static final String WORKFLOW_NAME_MAX_LENGTH_OUT = "WORKFLOW_NAME_MAX_LENGTH_OUT"; // 워크플로우 명은 최대 20글자까지 입력할 수 있습니다. |
| | | public static final String WORKFLOW_USED_NAME = "WORKFLOW_USED_NAME"; // 워크플로우 명이 이미 사용되고 있습니다. |
| | | public static final String WORKFLOW_TRANSITION_NOT_EXIST = "WORKFLOW_TRANSITION_NOT_EXIST"; // 워크플로우 전이가 존재하지 않습니다. |
| | | public static final String WORKFLOW_USED_ISSUE_TYPE = "WORKFLOW_USED_ISSUE_TYPE"; // 워크플로우가 이슈 타입에서 사용되고 있어서 삭제할 수 없습니다. |
| | | public static final String WORKFLOW_ISOLATION = "WORKFLOW_ISOLATION"; // 워크플로우에 고립된 이슈 상태가 존재합니다. |
| | | public static final String WORKFLOW_REMOVE_NOT_SELECT = "WORKFLOW_REMOVE_NOT_SELECT"; // 삭제할 워크플로우가 선택되지 않았습니다. |
| | | public static final String WORKFLOW_REQUIRE_ISSUE_STATUS_TYPE_TO_READY = "WORKFLOW_REQUIRE_ISSUE_STATUS_TYPE_TO_READY"; // 워크플로우에는 상태 속성 '대기' 인 이슈 상태가 1개 이상 존재해야 합니다. |
| | | public static final String WORKFLOW_REQUIRE_ISSUE_STATUS_TYPE_TO_OPEN = "WORKFLOW_REQUIRE_ISSUE_STATUS_TYPE_TO_OPEN"; // 워크플로우에는 상태 속성 '진행' 인 이슈 상태가 1개 이상 존재해야 합니다. |
| | | public static final String WORKFLOW_REQUIRE_ISSUE_STATUS_TYPE_TO_CLOSE = "WORKFLOW_REQUIRE_ISSUE_STATUS_TYPE_TO_CLOSE"; // 워크플로우에는 상태 속성 '종료' 인 이슈 상태가 1개 이상 존재해야 합니다. |
| | | |
| | | public static final String CUSTOM_FIELD_NOT_EXIST = "CUSTOM_FIELD_NOT_EXIST"; // 사용자 정의 필드가 존재하지 않습니다. |
| | | public static final String CUSTOM_FIELD_NOT_NAME = "CUSTOM_FIELD_NOT_NAME"; // 사용자 정의 필드명이 입력되지 않았습니다. |
| | | public static final String CUSTOM_FIELD_NAME_MAX_LENGTH_OUT = "CUSTOM_FIELD_NAME_MAX_LENGTH_OUT"; // 사용자 정의 필드명은 최대 50글자까지 입력할 수 있습니다. |
| | | public static final String CUSTOM_FIELD_USED_NAME = "CUSTOM_FIELD_USED_NAME"; // 사용자 정의 필드 명이 이미 사용되고 있습니다. |
| | | public static final String CUSTOM_FIELD_REMOVE_NOT_SELECT = "CUSTOM_FIELD_REMOVE_NOT_SELECT"; // 삭제할 사용자 정의 필드가 선택되지 않았습니다. |
| | | public static final String CUSTOM_FIELD_OPTIONS_NOT_USE_INPUT_FIELD = "CUSTOM_FIELD_OPTIONS_NOT_USE_INPUT_FIELD"; // 문자열 필드는 옵션 값을 사용할 수 없습니다. |
| | | public static final String CUSTOM_FIELD_OPTIONS_NOT_EXIST_DEFAULT_VALUE = "CUSTOM_FIELD_OPTIONS_NOT_EXIST_DEFAULT_VALUE"; // 사용자 정의 필드 기본 값이 옵션에 존재하지 않습니다. |
| | | public static final String CUSTOM_FIELD_OPTIONS_USED_EXIST_DEFAULT_VALUE = "CUSTOM_FIELD_OPTIONS_USED_EXIST_DEFAULT_VALUE"; // 사용자 정의 필드 기본 값에 중복된 값이 존재합니다. |
| | | public static final String CUSTOM_FIELD_OPTIONS_NOT_USE_MULTI_DEFAULT_VALUE = "CUSTOM_FIELD_OPTIONS_NOT_USE_MULTI_DEFAULT_VALUE"; // 사용자 정의 필드 옵션 값에 대한 기본 값으로 2개 이상 지정할 수 없습니다. |
| | | public static final String CUSTOM_FIELD_OPTIONS_NOT_EMPTY_VALUE = "CUSTOM_FIELD_OPTIONS_NOT_EMPTY_VALUE"; // 사용자 정의 필드 옵션 값에 공백을 등록할 수 없습니다. |
| | | public static final String CUSTOM_FIELD_OPTIONS_NOT_VALUE = "CUSTOM_FIELD_OPTIONS_NOT_VALUE"; // 사용자 정의 필드 옵션 값이 입력되지 않았습니다. |
| | | public static final String CUSTOM_FIELD_TEXT_TYPE_MAX_LENGTH_OUT = "CUSTOM_FIELD_TEXT_TYPE_MAX_LENGTH_OUT"; // 사용자 정의 문자열 필드는 최대 100글자까지 입력할 수 있습니다. |
| | | public static final String CUSTOM_FIELD_DEFAULT_VALUE_MAX_LENGTH_OUT = "CUSTOM_FIELD_DEFAULT_VALUE_MAX_LENGTH_OUT"; // 사용자 정의 필드의 기본 값 필드는 최대 100글자까지 입력할 수 있습니다. |
| | | public static final String CUSTOM_FIELD_OPTION_VALUE_MAX_LENGTH_OUT = "CUSTOM_FIELD_OPTION_VALUE_MAX_LENGTH_OUT"; // 사용자 정의 필드 옵션 값은 최대 15글자까지 입력할 수 있습니다. |
| | | |
| | | public static final String ISSUE_TYPE_NOT_EXIST = "ISSUE_TYPE_NOT_EXIST"; // 이슈 유형이 존재하지 않습니다. |
| | | public static final String ISSUE_TYPE_NOT_NAME = "ISSUE_TYPE_NOT_NAME"; // 이슈 유형 명이 입력되지 않았습니다. |
| | | public static final String ISSUE_TYPE_NAME_MAX_LENGTH_OUT = "ISSUE_TYPE_NAME_MAX_LENGTH_OUT"; // 이슈 유형은 최대 50글자까지 입력할 수 있습니다. |
| | | public static final String ISSUE_TYPE_USED_NAME = "ISSUE_TYPE_USED_NAME"; // 이슈 유형 명이 이미 사용되고 있습니다. |
| | | public static final String ISSUE_TYPE_REMOVE_NOT_SELECT = "ISSUE_TYPE_REMOVE_NOT_SELECT"; // 삭제할 이슈 유형이 선택되지 않았습니다. |
| | | public static final String ISSUE_TYPE_NOT_COLOR = "ISSUE_TYPE_NOT_COLOR"; // 이슈 유형에 색상이 입력되지 않았습니다. |
| | | public static final String ISSUE_TYPE_USE_ISSUES = "ISSUE_TYPE_USE_ISSUES"; // 이슈 유형을 사용하고 있는 이슈가 존재하고 있습니다. |
| | | |
| | | public static final String PRIORITY_NOT_EXIST = "PRIORITY_NOT_EXIST"; // 우선순위가 존재하지 않습니다. |
| | | public static final String SEVERITY_NOT_EXIST = "SEVERITY_NOT_EXIST"; // 중요도가 존재하지 않습니다. |
| | | |
| | | public static final String ISSUE_NOT_EXIST = "ISSUE_NOT_EXIST"; // 이슈가 존재하지 않습니다. |
| | | public static final String ISSUE_NUMBER_GENERATOR_NOT_EXIST = "ISSUE_NUMBER_GENERATOR_NOT_EXIST"; // 이슈 번호 제너레이터가 존재하지 않습니다. |
| | | public static final String ISSUE_NUMBER_NOT_EXIST = "ISSUE_NUMBER_NOT_EXIST"; // 이슈 번호가 존재하지 않습니다. |
| | | public static final String ISSUE_TITLE_MAX_LENGTH_OUT = "ISSUE_TITLE_MAX_LENGTH_OUT"; // 이슈 제목은 최대 300글자까지 입력할 수 있습니다. |
| | | public static final String ISSUE_NOT_MODIFY_PERMISSION = "ISSUE_NOT_MODIFY_PERMISSION"; // 이슈 수정 권한이 없습니다. |
| | | public static final String ISSUE_REMOVE_NOT_SELECT = "ISSUE_REMOVE_NOT_SELECT"; // 삭제할 이슈가 선택되지 않았습니다. |
| | | public static final String ISSUE_NO_TITLE = "ISSUE_NO_TITLE"; // 이슈 제목이 입력되지 않았습니다. |
| | | public static final String ISSUE_NOT_SEND_USER = "ISSUE_NOT_SEND_USER"; // 이슈 발송 대상자를 선택하지 않았습니다. |
| | | |
| | | public static final String ISSUE_COMMENT_REMOVE_NOT_SELECT = "ISSUE_COMMENT_REMOVE_NOT_SELECT"; // 삭제할 댓글을 선택하지 않았습니다. |
| | | public static final String ISSUE_COMMENT_NOT_EXIST = "ISSUE_COMMENT_NOT_EXIST"; // 댓글이 존재하지 않습니다. |
| | | public static final String ISSUE_COMMENT_NOT_REMOVE_PERMISSION = "ISSUE_COMMENT_NOT_REMOVE_PERMISSION"; // 댓글을 삭제할 수 있는 권한이 없습니다. |
| | | public static final String ISSUE_COMMENT_NOT_COMMENT = "ISSUE_COMMENT_NOT_COMMENT"; // 댓글이 입력되지 않았습니다. |
| | | public static final String ISSUE_COMMENT_MAX_LENGTH_OUT = "ISSUE_COMMENT_MAX_LENGTH_OUT"; // 댓글은 최대 300글자까지 입력할 수 있습니다. |
| | | |
| | | public static final String ISSUE_RESERVATION_NOT_EXIST = "ISSUE_RESERVATION_NOT_EXIST"; // 이슈 발생 예약 정보가 존재하지 않습니다. |
| | | public static final String ISSUE_RESERVATION_VALUE_INVALID = "ISSUE_RESERVATION_VALUE_INVALID"; // 이슈 발생 예약일이 잘못되었습니다. |
| | | |
| | | |
| | | public static final String USER_WORKSPACE_NOT_EXIST = "USER_WORKSPACE_NOT_EXIST"; // 업무 공간 사용자 연결 정보가 존재하지 않습니다. |
| | | |
| | | public static final String WIDGET_SEARCH_DATE_NOT_FOUND = "WIDGET_SEARCH_DATE_NOT_FOUND"; // 위젯 검색 일자를 찾을 수 없습니다. |
| | | |
| | | public static final String USER_NO_NAME = "USER_NO_NAME"; // 이름이 입력 되지 않았습니다. |
| | | public static final String USER_NAME_LENGTH_EXCESS = "USER_NAME_LENGTH_EXCESS"; // 사용자 이름은 최대 50글자만 가능합니다. |
| | | public static final String USER_NO_EMAIL = "USER_NO_EMAIL"; // 이메일 주소가 입력 되지 않았습니다. |
| | | public static final String USER_INVALID_EMAIL = "INVALID_EMAIL_ADDRESS"; // 잘못된 이메일 주소 입니다. |
| | | public static final String USER_USED_EMAIL = "USER_USED_EMAIL"; // 이미 가입된 이메일 주소 입니다. |
| | | public static final String USER_NO_PASSWORD = "USER_NO_PASSWORD"; // 비밀번호가 입력 되지 않았습니다. |
| | | public static final String USER_NOT_MODIFY_SELF = "USER_NOT_MODIFY_SELF"; // 다른 사람의 정보를 수정할 수 없습니다. |
| | | public static final String USER_PHONE_MAX_LENGTH_OUT = "USER_PHONE_MAX_LENGTH_OUT"; // 연락처는 최대 20글자까지 입력할 수 있습니다. |
| | | public static final String USER_PHONE_ONLY_NUMBER = "USER_PHONE_ONLY_NUMBER"; // 연락처는 숫자만 입력할 수 있습니다. |
| | | public static final String USER_PASSWORD_MAX_LENGTH_OUT = "USER_PASSWORD_MAX_LENGTH_OUT"; // 비밀번호는 최대 20글자까지 입력할 수 있습니다. |
| | | public static final String USER_INVALID_CURRENT_PASSWORD = "USER_INVALID_CURRENT_PASSWORD"; // 입력한 현재 비밀번호가 잘못되었습니다. |
| | | public static final String USER_INVALID_LICENSEKEY = "USER_INVALID_LICENSEKEY"; // 입력한 현재 라이센스가 잘못되었습니다. |
| | | public static final String USER_PASSWORD_SAME_NEW_PASSWORD = "USER_PASSWORD_SAME_NEW_PASSWORD"; // 현재 사용하는 비밀번호와 변경하려는 비밀번호는 달라야 합니다. |
| | | public static final String USER_PASSWORD_NOT_SAME_CONFIRM_PASSWORD = "USER_PASSWORD_NOT_SAME_CONFIRM_PASSWORD"; // 신규 비밀번호와 신규 비밀번호 확인 필드에 입력한 비밀번호가 다릅니다. |
| | | public static final String USER_WITH_DRAW_EXIST = "USER_WITH_DRAW_EXIST"; // 해당 계정은 회원 탈퇴 기록이 있습니다. |
| | | public static final String USER_PROFILE_SIZE_NOT_ALLOW = "USER_PROFILE_SIZE_NOT_ALLOW"; // 사용자 프로필 사이즈가 너무 큽니다. 10MB 이하 파일로 업로드해주세요. |
| | | public static final String USER_PROFILE_UPLOAD_FILE_TYPE_NOT_ALLOW = "USER_PROFILE_UPLOAD_FILE_TYPE_NOT_ALLOW"; // 프로필 파일은 jpg, png 만 가능합니다. |
| | | public static final String USER_NOT_EQUAL_PASSWORD = "USER_NOT_EQUAL_PASSWORD"; // 비밀번호가 맞지 않습니다. |
| | | public static final String USER_NOT_EXIST = "USER_NOT_EXIST"; // 사용자가 존재하지 않습니다. |
| | | public static final String USER_NOT_AUTHORIZED = "USER_NOT_AUTHORIZED"; // 사용자 인증 권한이 없습니다. |
| | | public static final String USER_EXPIRED_PASSWORD = "USER_EXPIRED_PASSWORD"; // 비밀번호가 만료되었습니다. |
| | | public static final String USER_RETURN_PASSWORD_NOT_PROVIDER_SOCIAL_JOIN_USER = "USER_RETURN_PASSWORD_NOT_PROVIDER_SOCIAL_JOIN_USER"; // 비밀번호 찾기 기능을 소셜 계정 가입 사용자는 사용할 수 없습니다. |
| | | public static final String USER_NOT_USE_ACTIVE_STATUS = "USER_NOT_USE_ACTIVE_STATUS"; // 사용자는 활성 상태가 아니면 로그인할 수 없습니다. |
| | | |
| | | public static final String EXCEL_NOT_EXTENSION = "EXCEL_NOT_EXTENSION"; // 엑셀 파일 확장자 (xlsx)만 업로드가 가능합니다. |
| | | public static final String EXCEL_DOWNLOAD_MAX_ROWS_OVER = "EXCEL_DOWNLOAD_MAX_ROWS_OVER"; // 검색된 엑셀 행이 1,000건을 초과하여 다운로드 할 수 없습니다. 검색 조건을 사용하여 1,000 건 이하로 다운로드를 진행해야 합니다. |
| | | public static final String EXCEL_IMPORT_MAX_ROWS_OVER = "EXCEL_IMPORT_MAX_ROWS_OVER"; // 엑셀 업로드로 이슈 등록은 최대 1,000 건까지만 가능합니다. |
| | | public static final String EXCEL_CONDITIONS_NOT_EXIST = "EXCEL_CONDITIONS_NOT_EXIST"; // 엑셀 다운로드에 필요한 검색 조건을 찾을 수 없습니다. |
| | | public static final String EXCEL_EMPTY_CELL = "EXCEL_EMPTY_CELL"; // 엑셀 헤더 부분 셀을 찾을 수 없습니다. 엑셀 작성 양식에 문제가 있습니다. |
| | | public static final String EXCEL_HEADER_EMPTY_CELL = "EXCEL_HEADER_EMPTY_CELL"; // 엑셀 헤더에 빈 셀이 있습니다. |
| | | public static final String EXCEL_IMPORT_ISSUE_TITLE_IS_NULL = "EXCEL_IMPORT_ISSUE_TITLE_IS_NULL"; // 다음 엑셀 라인에서 이슈 제목이 입력지 않았습니다. |
| | | public static final String EXCEL_IMPORT_PROJECT_KEY_IS_NULL = "EXCEL_IMPORT_PROJECT_KEY_IS_NULL"; // 다음 엑셀 라인에서 프로젝트 키가 입력되지 않았습니다. |
| | | public static final String EXCEL_IMPORT_PROJECT_NOT_EXIST = "EXCEL_IMPORT_PROJECT_NOT_EXIST"; // 다음 엑셀 라인에서 입력된 프로젝트 키로 검색되는 프로젝트가 없습니다. |
| | | public static final String EXCEL_IMPORT_ISSUE_TYPE_IS_NULL = "EXCEL_IMPORT_ISSUE_TYPE_IS_NULL"; // 다음 엑셀 라인에서 이슈 타입 명이 입력되지 않았습니다. |
| | | public static final String EXCEL_IMPORT_ISSUE_TYPE_NOT_EXIST = "EXCEL_IMPORT_ISSUE_TYPE_NOT_EXIST"; // 다음 엑셀 라인에서 입력된 이슈 타입 명으로 검색되는 이슈 타입이 없습니다. |
| | | public static final String EXCEL_IMPORT_ISSUE_STATUS_READY_NOT_EXIST = "EXCEL_IMPORT_ISSUE_STATUS_READY_NOT_EXIST"; // 다음 엑셀 라인에서 입력된 이슈 타입의 워크플로우에서 상태 속성 '대기'인 상태가 없습니다. |
| | | public static final String EXCEL_IMPORT_PRIORITY_IS_NULL = "EXCEL_IMPORT_PRIORITY_IS_NULL"; // 다음 엑셀 라인에서 우선순위 명이 입력되지 않았습니다. |
| | | public static final String EXCEL_IMPORT_PRIORITY_NOT_EXIST = "EXCEL_IMPORT_PRIORITY_NOT_EXIST"; // 다음 엑셀 라인에서 입력된 우선순위 명으로 검색되는 우선순위가 없습니다. |
| | | public static final String EXCEL_IMPORT_SEVERITY_IS_NULL = "EXCEL_IMPORT_SEVERITY_IS_NULL"; // 다음 엑셀 라인에서 중요도 명이 입력되지 않았습니다. |
| | | public static final String EXCEL_IMPORT_SEVERITY_NOT_EXIST = "EXCEL_IMPORT_SEVERITY_NOT_EXIST"; // 다음 엑셀 라인에서 입력된 중요도 명으로 검색되는 우선순위가 없습니다. |
| | | public static final String EXCEL_IMPORT_PERIOD_NOT_VALIDITY = "EXCEL_IMPORT_PERIOD_NOT_VALIDITY"; // 다음 엑셀 라인에서 입력한 시작일, 종료일에 문제가 있습니다. 시작일은 종료일보다 빨라야 합니다. |
| | | public static final String EXCEL_IMPORT_PERIOD_NOT_VALIDITY_EMPTY = "EXCEL_IMPORT_PERIOD_NOT_VALIDITY_EMPTY"; // 다음 엑셀 라인에서 입력한 시작일, 종료일에 문제가 있습니다. 공백이 포함되어 있는지 확인 후 공백을 제거하세요. |
| | | public static final String EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY = "EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY"; // 다음 엑셀 라인에서 입력한 사용자 정의 필드 값이 유효하지 않습니다. |
| | | public static final String EXCEL_IMPORT_HEADER_CUSTOM_FIELD_NOT_EXIST = "EXCEL_IMPORT_HEADER_CUSTOM_FIELD_NOT_EXIST"; // 등록하려는 사용자 정의 필드를 찾을 수 없습니다. 해당 사용자 정의필드의 이름이 변경되었거나 삭제되었습니다. |
| | | |
| | | public static final String NOTICE_NOT_EXIST = "NOTICE_NOT_EXIST"; // 공지사항이 존재하지 않습니다. |
| | | public static final String NOTICE_EMPTY_CONTENT = "NOTICE_EMPTY_CONTENT"; // 공지사항 제목 및 내용 중 입력 값이 없는 필드가 있습니다. |
| | | |
| | | public static final String FAQ_NOT_EXIST = "FAQ_NOT_EXIST"; // FAQ가 존재하지 않습니다. |
| | | public static final String FAQ_EMPTY_CONTENT = "FAQ_EMPTY_CONTENT"; // FAQ 제목 및 내용 중 입력 값이 없는 필드가 있습니다. |
| | | |
| | | public static final String GUIDE_NOT_EXIST="GUIDE_NOT_EXIST"; |
| | | public static final String GUIDE_EMPTY_CONTENT="GUIDE_EMPTY_CONTENT"; |
| | | |
| | | public static final String EVENT_NOT_EXIST="EVENT_NOT_EXIST"; |
| | | public static final String EVENT_EMPTY_CONTENT="EVENT_EMPTY_CONTENT"; |
| | | |
| | | public static final String QNA_NOT_EXIST = "QNA_NOT_EXIST"; // QNA 존재하지 않습니다. |
| | | public static final String QNA_EMPTY_CONTENT = "QNA_EMPTY_CONTENT"; // QNA 제목 및 내용 중 입력 값이 없는 필드가 있습니다. |
| | | |
| | | public static final String RESERVATION_EMAIL_TITLE = "RESERVATION_EMAIL_TITLE"; // [OWL ITS] 어제 이슈 및 활동 현황입니다. |
| | | public static final String FILE_TYPE_NOT_ALLOW = "FILE_TYPE_NOT_ALLOW"; // 허용되지 않은 파일 유형입니다. |
| | | |
| | | |
| | | public static final String ERR_FAILED_CONVERT_OBJECT = "ERR_FAILED_CONVERT_OBJECT"; // 데이터 변환을 실패했습니다. |
| | | public static final String TARGET_OBJECT_IS_NULL = "TARGET_OBJECT_IS_NULL"; // 타겟 객체가 Null 입니다. |
| | | public static final String SOURCE_OBJECT_IS_NULL = "SOURCE_OBJECT_IS_NULL"; // 소스 객체가 Null 입니다. |
| | | public static final String ERR_FAILED_CONVERT_JSON = "ERR_FAILED_CONVERT_JSON"; // 요청 데이터의 JSON 변환을 실패했습니다. |
| | | |
| | | public static final String NOT_READABLE_JSON_DATA = "NOT_READABLE_JSON_DATA"; // JSON 데이터를 읽을 수 없습니다. |
| | | public static final String SUCCESS_REQUEST = "SUCCESS_REQUEST"; // 요청이 성공하였습니다. |
| | | public static final String SESSION_EXPIRED = "SESSION_EXPIRED"; // 사용자 세션이 만료 되었습니다. |
| | | |
| | | public static final String PAGE_NOT_EXIST_INFO = "PAGE_NOT_EXIST_INFO"; // 페이지 정보를 찾을 수 없습니다. |
| | | public static final String PAGE_NEGATIVE_OR_NULL = "PAGE_NEGATIVE_OR_NULL"; // 요청한 페이지 정보가 잘못되었습니다. |
| | | public static final String PAGE_SIZE_NEGATIVE_OR_NULL = "PAGE_SIZE_NEGATIVE_OR_NULL"; // 요청한 페이지 크기가 잘못되었습니다. |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.AttachedType; |
| | | import kr.wisestone.owl.domain.enumType.FileType; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | @Entity |
| | | public class AttachedFile extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 847376294732544822L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String path; |
| | | private Long size; |
| | | private String contentType; |
| | | private String awsKey; |
| | | @Enumerated(EnumType.STRING) |
| | | private FileType fileType; |
| | | |
| | | @Enumerated(EnumType.STRING) |
| | | private AttachedType attachedType; |
| | | |
| | | @ManyToOne(fetch= FetchType.EAGER) |
| | | @JoinColumn(name="issue_id") |
| | | private Issue issue; |
| | | // 파일 다운로드 오류 해결 |
| | | @ManyToOne(fetch= FetchType.EAGER) |
| | | @JoinColumn(name="workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public AttachedFile() { |
| | | } |
| | | |
| | | public AttachedFile(String name, Long size, String contentType, String path) { |
| | | this.name = name; |
| | | this.path = path; |
| | | this.size = size; |
| | | this.contentType = contentType; |
| | | } |
| | | |
| | | public AttachedFile(String name, Long size, String contentType, String path, String awsKey, Issue issue, Workspace workspace, FileType fileType, AttachedType attachedType) { |
| | | this.name = name; |
| | | this.size = size; |
| | | this.contentType = contentType; |
| | | this.path = path; |
| | | this.awsKey = awsKey; |
| | | this.issue = issue; |
| | | this.workspace = workspace; |
| | | this.fileType = fileType; |
| | | this.attachedType = attachedType; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getPath() { |
| | | return path; |
| | | } |
| | | |
| | | public void setPath(String path) { |
| | | this.path = path; |
| | | } |
| | | |
| | | public Long getSize() { |
| | | return size; |
| | | } |
| | | |
| | | public void setSize(Long size) { |
| | | this.size = size; |
| | | } |
| | | |
| | | public String getContentType() { |
| | | return contentType; |
| | | } |
| | | |
| | | public void setContentType(String contentType) { |
| | | this.contentType = contentType; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public FileType getFileType() { |
| | | return fileType; |
| | | } |
| | | |
| | | public void setFileType(FileType fileType) { |
| | | this.fileType = fileType; |
| | | } |
| | | |
| | | public String getAwsKey() { |
| | | return awsKey; |
| | | } |
| | | |
| | | public void setAwsKey(String awsKey) { |
| | | this.awsKey = awsKey; |
| | | } |
| | | |
| | | public AttachedType getAttachedType() { |
| | | return attachedType; |
| | | } |
| | | |
| | | public void setAttachedType(AttachedType attachedType) { |
| | | this.attachedType = attachedType; |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * 상기 프로그램에 대한 저작권을 포함한 지적재산권은 WiseStone에 있으며, |
| | | * WiseStone이 명시적으로 허용하지 않은 사용, 복사, 변경, 제3자에의 공개, |
| | | * 배포는 엄격히 금지되며, WiseStone의 지적재산권 침해에 해당됩니다. |
| | | * (Copyright ⓒ 2014 WiseStone Co., Ltd. All Rights Reserved|Confidential) |
| | | * ----------------------------------------------------------------------------- |
| | | * You are strictly prohibited to copy, disclose, distribute, modify, |
| | | * or use this program in part or as a whole without the prior written |
| | | * consent of WiseStone Co., Ltd. WiseStone Co., Ltd., owns the |
| | | * intellectual property rights in and to this program. |
| | | * (Copyright ⓒ 2014 WiseStone Co., Ltd. All Rights Reserved|Confidential) |
| | | * ----------------------------------------------------------------------------- |
| | | */ |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.util.Date; |
| | | |
| | | @MappedSuperclass |
| | | public class BaseEntity { |
| | | @Basic |
| | | @Column(insertable = true, updatable = false) |
| | | Long registerId; |
| | | @Column(insertable = true, updatable = false) |
| | | @Temporal(TemporalType.TIMESTAMP) |
| | | Date registerDate; |
| | | |
| | | @Basic |
| | | @Column(insertable = true, updatable = true) |
| | | Long modifyId; |
| | | @Column(insertable = true, updatable = true) |
| | | @Temporal(TemporalType.TIMESTAMP) |
| | | Date modifyDate; |
| | | |
| | | public Long getRegisterId() { |
| | | return registerId; |
| | | } |
| | | |
| | | public void setRegisterId(Long registerId) { |
| | | this.registerId = registerId; |
| | | } |
| | | |
| | | public Date getRegisterDate() { |
| | | return registerDate; |
| | | } |
| | | |
| | | public void setRegisterDate(Date registerDate) { |
| | | this.registerDate = registerDate; |
| | | } |
| | | |
| | | public Long getModifyId() { |
| | | return modifyId; |
| | | } |
| | | |
| | | public void setModifyId(Long modifyId) { |
| | | this.modifyId = modifyId; |
| | | } |
| | | |
| | | public Date getModifyDate() { |
| | | return modifyDate; |
| | | } |
| | | |
| | | public void setModifyDate(Date modifyDate) { |
| | | this.modifyDate = modifyDate; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append("BaseEntity [registerId=").append(this.registerId) |
| | | .append(", registerDate=").append(this.registerDate) |
| | | .append(", modifyId=").append(this.modifyId).append(", modifyDate=") |
| | | .append(this.modifyDate).append("]"); |
| | | return builder.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class CustomField extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | |
| | | @Enumerated(EnumType.STRING) |
| | | private CustomFieldType customFieldType; |
| | | private String defaultValue; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToMany(mappedBy = "customField", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueTypeCustomField> issueTypeCustomFields = new HashSet<>(); |
| | | |
| | | @OrderBy("id asc") |
| | | @OneToMany(mappedBy = "customField", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<CustomFieldValue> customFieldValues = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "customField", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueCustomFieldValue> issueCustomFieldValues = new HashSet<>(); |
| | | |
| | | private String useFlag; |
| | | |
| | | public CustomField() { |
| | | } |
| | | |
| | | public String getUse() { return useFlag; } |
| | | |
| | | public void setUse(String useFlag) { this.useFlag = useFlag; } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public CustomFieldType getCustomFieldType() { |
| | | return customFieldType; |
| | | } |
| | | |
| | | public void setCustomFieldType(CustomFieldType customFieldType) { |
| | | this.customFieldType = customFieldType; |
| | | } |
| | | |
| | | public String getDefaultValue() { |
| | | return defaultValue; |
| | | } |
| | | |
| | | public void setDefaultValue(String defaultValue) { |
| | | this.defaultValue = defaultValue; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Set<IssueTypeCustomField> getIssueTypeCustomFields() { |
| | | return issueTypeCustomFields; |
| | | } |
| | | |
| | | public void setIssueTypeCustomFields(Set<IssueTypeCustomField> issueTypeCustomFields) { |
| | | this.issueTypeCustomFields = issueTypeCustomFields; |
| | | } |
| | | |
| | | public Set<CustomFieldValue> getCustomFieldValues() { |
| | | return customFieldValues; |
| | | } |
| | | |
| | | public void setCustomFieldValues(Set<CustomFieldValue> customFieldValues) { |
| | | this.customFieldValues = customFieldValues; |
| | | } |
| | | |
| | | public Set<IssueCustomFieldValue> getIssueCustomFieldValues() { |
| | | return issueCustomFieldValues; |
| | | } |
| | | |
| | | public void setIssueCustomFieldValues(Set<IssueCustomFieldValue> issueCustomFieldValues) { |
| | | this.issueCustomFieldValues = issueCustomFieldValues; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class CustomFieldValue extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String value; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "custom_field_id") |
| | | private CustomField customField; |
| | | |
| | | public CustomFieldValue(){} |
| | | |
| | | public CustomFieldValue(CustomField customField, String value){ |
| | | this.customField = customField; |
| | | this.value = value; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getValue() { |
| | | return value; |
| | | } |
| | | |
| | | public void setValue(String value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | public CustomField getCustomField() { |
| | | return customField; |
| | | } |
| | | |
| | | public void setCustomField(CustomField customField) { |
| | | this.customField = customField; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.GenerationType; |
| | | import javax.persistence.Id; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-22 |
| | | */ |
| | | @Entity |
| | | public class Event extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final Integer ACTIVATION = 1; // 활성 |
| | | public static final Integer INACTIVATION = 0; // 비활성 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String title; |
| | | private String description; |
| | | private Integer status; |
| | | private String startDate; |
| | | private String endDate; |
| | | |
| | | public Event(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Integer getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(Integer status) { |
| | | this.status = status; |
| | | } |
| | | |
| | | public String getStartDate() { |
| | | return startDate; |
| | | } |
| | | |
| | | public void setStartDate(String startDate) { |
| | | this.startDate = startDate; |
| | | } |
| | | |
| | | public String getEndDate() { |
| | | return endDate; |
| | | } |
| | | |
| | | public void setEndDate(String endDate) { |
| | | this.endDate = endDate; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.GenerationType; |
| | | import javax.persistence.Id; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-22 |
| | | */ |
| | | @Entity |
| | | public class Faq extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final Integer ACTIVATION = 1; // 활성 |
| | | public static final Integer INACTIVATION = 0; // 비활성 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String title; |
| | | private String description; |
| | | private Integer status; |
| | | |
| | | public Faq(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Integer getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(Integer status) { |
| | | this.status = status; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.GenerationType; |
| | | import javax.persistence.Id; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-22 |
| | | */ |
| | | @Entity |
| | | public class Guide extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final Integer ACTIVATION = 1; // 활성 |
| | | public static final Integer INACTIVATION = 0; // 비활성 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String title; |
| | | private String description; |
| | | private Integer status; |
| | | |
| | | public Guide(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Integer getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(Integer status) { |
| | | this.status = status; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-03. |
| | | */ |
| | | @Entity |
| | | public class Issue extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | public static final String WORKSPACE_MANAGER = "WORKSPACE_MANAGER"; // 업무 공간 관리자 |
| | | public static final String PROJECT_MANAGER = "PROJECT_MANAGER"; // 프로젝트 관리자 |
| | | public static final String REGISTER = "REGISTER"; // 이슈 등록자 |
| | | public static final String ASSIGNEE = "ASSIGNEE"; // 이슈 담당자 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String title; |
| | | private String description; |
| | | private Long reverseIndex; |
| | | private Long issueNumber; |
| | | private String startDate; |
| | | private String completeDate; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name = "project_id") |
| | | private Project project; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name = "issue_status_id") |
| | | private IssueStatus issueStatus; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name = "issue_type_id") |
| | | private IssueType issueType; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name = "priority_id") |
| | | private Priority priority; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name = "severity_id") |
| | | private Severity severity; |
| | | |
| | | @OneToOne(mappedBy = "issue", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private IssueRisk issueRisk; |
| | | |
| | | @OrderBy(value="id DESC") |
| | | @OneToMany(mappedBy = "issue", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueUser> issueUsers = new HashSet<>(); |
| | | |
| | | @OrderBy(value="id DESC") |
| | | @OneToMany(mappedBy="issue", cascade={CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<AttachedFile> attachedFiles = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "issue", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<UserLikeIssue> userLikeIssues = new HashSet<>(); |
| | | |
| | | // 이력은 삭제 금지 |
| | | @OrderBy(value="id DESC") |
| | | @OneToMany(mappedBy="issue", cascade={CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueHistory> issueHistory = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy="issue", cascade={CascadeType.ALL}, orphanRemoval = true) |
| | | @OrderBy(value="id DESC") |
| | | private Set<IssueComment> issueComments = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "issue", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueCustomFieldValue> issueCustomFieldValues = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "issue", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueVersion> issueVersions = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "issue", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueRelation> issueRelations = new HashSet<>(); |
| | | |
| | | @OneToOne(mappedBy = "issue", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private IssueReservation issueReservation; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name = "workflow_status_id") |
| | | private WorkflowStatus workflowStatus; |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Long getReverseIndex() { |
| | | return reverseIndex; |
| | | } |
| | | |
| | | public void setReverseIndex(Long reverseIndex) { |
| | | this.reverseIndex = reverseIndex; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public IssueStatus getIssueStatus() { |
| | | return issueStatus; |
| | | } |
| | | |
| | | public void setIssueStatus(IssueStatus issueStatus) { |
| | | this.issueStatus = issueStatus; |
| | | } |
| | | |
| | | public IssueType getIssueType() { |
| | | return issueType; |
| | | } |
| | | |
| | | public void setIssueType(IssueType issueType) { |
| | | this.issueType = issueType; |
| | | } |
| | | |
| | | public Priority getPriority() { |
| | | return priority; |
| | | } |
| | | |
| | | public void setPriority(Priority priority) { |
| | | this.priority = priority; |
| | | } |
| | | |
| | | public Severity getSeverity() { |
| | | return severity; |
| | | } |
| | | |
| | | public void setSeverity(Severity severity) { |
| | | this.severity = severity; |
| | | } |
| | | |
| | | public IssueRisk getIssueRisk() { |
| | | return issueRisk; |
| | | } |
| | | |
| | | public void setIssueRisk(IssueRisk issueRisk) { |
| | | this.issueRisk = issueRisk; |
| | | } |
| | | |
| | | public Long getIssueNumber() { |
| | | return issueNumber; |
| | | } |
| | | |
| | | public void setIssueNumber(Long issueNumber) { |
| | | this.issueNumber = issueNumber; |
| | | } |
| | | |
| | | public Set<IssueUser> getIssueUsers() { |
| | | return issueUsers; |
| | | } |
| | | |
| | | public void setIssueUsers(Set<IssueUser> issueUsers) { |
| | | this.issueUsers = issueUsers; |
| | | } |
| | | |
| | | public Set<AttachedFile> getAttachedFiles() { |
| | | return attachedFiles; |
| | | } |
| | | |
| | | public void setAttachedFiles(Set<AttachedFile> attachedFiles) { |
| | | this.attachedFiles = attachedFiles; |
| | | } |
| | | |
| | | public Set<UserLikeIssue> getUserLikeIssues() { |
| | | return userLikeIssues; |
| | | } |
| | | |
| | | public void setUserLikeIssues(Set<UserLikeIssue> userLikeIssues) { |
| | | this.userLikeIssues = userLikeIssues; |
| | | } |
| | | |
| | | public Set<IssueHistory> getIssueHistory() { |
| | | return issueHistory; |
| | | } |
| | | |
| | | public void setIssueHistory(Set<IssueHistory> issueHistory) { |
| | | this.issueHistory = issueHistory; |
| | | } |
| | | |
| | | public Set<IssueComment> getIssueComments() { |
| | | return issueComments; |
| | | } |
| | | |
| | | public void setIssueComments(Set<IssueComment> issueComments) { |
| | | this.issueComments = issueComments; |
| | | } |
| | | |
| | | public Set<IssueCustomFieldValue> getIssueCustomFieldValues() { |
| | | return issueCustomFieldValues; |
| | | } |
| | | |
| | | public void setIssueCustomFieldValues(Set<IssueCustomFieldValue> issueCustomFieldValues) { |
| | | this.issueCustomFieldValues = issueCustomFieldValues; |
| | | } |
| | | |
| | | public String getStartDate() { |
| | | return startDate; |
| | | } |
| | | |
| | | public void setStartDate(String startDate) { |
| | | this.startDate = startDate; |
| | | } |
| | | |
| | | public String getCompleteDate() { |
| | | return completeDate; |
| | | } |
| | | |
| | | public void setCompleteDate(String completeDate) { |
| | | this.completeDate = completeDate; |
| | | } |
| | | |
| | | public IssueReservation getIssueReservation() { |
| | | return issueReservation; |
| | | } |
| | | |
| | | public void setIssueReservation(IssueReservation issueReservation) { |
| | | this.issueReservation = issueReservation; |
| | | } |
| | | |
| | | public Set<IssueVersion> getIssueVersions() { |
| | | return issueVersions; |
| | | } |
| | | |
| | | public void setIssueVersions(Set<IssueVersion> issueVersions) { |
| | | this.issueVersions = issueVersions; |
| | | } |
| | | |
| | | public WorkflowStatus getWorkflowStatus() { |
| | | return workflowStatus; |
| | | } |
| | | |
| | | public void setWorkflowStatus(WorkflowStatus workflowStatus) { |
| | | this.workflowStatus = workflowStatus; |
| | | } |
| | | |
| | | public Set<IssueRelation> getIssueRelations() { |
| | | return issueRelations; |
| | | } |
| | | |
| | | public void setIssueRelations(Set<IssueRelation> issueRelations) { |
| | | this.issueRelations = issueRelations; |
| | | } |
| | | |
| | | public void clearIssueRelations() { |
| | | this.issueRelations.clear(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.*; |
| | | |
| | | |
| | | @Entity |
| | | public class IssueComment extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String description; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public IssueComment() { |
| | | } |
| | | |
| | | public IssueComment(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class IssueCustomFieldValue extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String useValue; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "issue_type_custom_field_id") |
| | | private IssueTypeCustomField issueTypeCustomField; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "custom_field_id") |
| | | private CustomField customField; |
| | | |
| | | public IssueCustomFieldValue(){} |
| | | |
| | | public IssueCustomFieldValue(Issue issue, CustomField customField, IssueTypeCustomField issueTypeCustomField, String userValue){ |
| | | this.issue = issue; |
| | | this.customField = customField; |
| | | this.issueTypeCustomField = issueTypeCustomField; |
| | | this.useValue = userValue; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getUseValue() { |
| | | return useValue; |
| | | } |
| | | |
| | | public void setUseValue(String useValue) { |
| | | this.useValue = useValue; |
| | | } |
| | | |
| | | public IssueTypeCustomField getIssueTypeCustomField() { |
| | | return issueTypeCustomField; |
| | | } |
| | | |
| | | public void setIssueTypeCustomField(IssueTypeCustomField issueTypeCustomField) { |
| | | this.issueTypeCustomField = issueTypeCustomField; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public CustomField getCustomField() { |
| | | return customField; |
| | | } |
| | | |
| | | public void setCustomField(CustomField customField) { |
| | | this.customField = customField; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.IssueHistoryType; |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-26. |
| | | */ |
| | | @Entity |
| | | public class IssueHistory extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String description; |
| | | |
| | | @Enumerated(EnumType.STRING) |
| | | private IssueHistoryType issueHistoryType; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="project_id") |
| | | private Project project; |
| | | |
| | | public IssueHistory(){} |
| | | |
| | | public IssueHistory(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public IssueHistoryType getIssueHistoryType() { |
| | | return issueHistoryType; |
| | | } |
| | | |
| | | public void setIssueHistoryType(IssueHistoryType issueHistoryType) { |
| | | this.issueHistoryType = issueHistoryType; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class IssueNumberGenerator extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private Long number; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "project_id") |
| | | private Project project; |
| | | |
| | | public IssueNumberGenerator(){} |
| | | |
| | | public IssueNumberGenerator(Project project, Long number) { |
| | | this.project = project; |
| | | this.number = number; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public Long getNumber() { |
| | | return number; |
| | | } |
| | | |
| | | public void setNumber(Long number) { |
| | | this.number = number; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Create By maprex / 2021-05-13 |
| | | */ |
| | | @Entity |
| | | public class IssueRelation extends BaseEntity implements Serializable { |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="relation_issue_id") |
| | | private Issue relationIssue; |
| | | |
| | | private Long relationIssueType; |
| | | |
| | | public void IssueRelation(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Issue getRelationIssue() { |
| | | return relationIssue; |
| | | } |
| | | |
| | | public void setRelationIssue(Issue issue) { |
| | | this.relationIssue = issue; |
| | | } |
| | | |
| | | public Long getRelationIssueType() { return relationIssueType; } |
| | | |
| | | public void setRelationIssueType(Long relationType) { this.relationIssueType = relationType; } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.IssueReservationType; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-07 |
| | | */ |
| | | @Entity |
| | | public class IssueReservation extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | @Enumerated(EnumType.STRING) |
| | | private IssueReservationType issueReservationType; |
| | | |
| | | private String reservation; |
| | | |
| | | @OneToOne |
| | | @JoinColumn(name = "issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public IssueReservation(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public IssueReservationType getIssueReservationType() { |
| | | return issueReservationType; |
| | | } |
| | | |
| | | public void setIssueReservationType(IssueReservationType issueReservationType) { |
| | | this.issueReservationType = issueReservationType; |
| | | } |
| | | |
| | | public String getReservation() { |
| | | return reservation; |
| | | } |
| | | |
| | | public void setReservation(String reservation) { |
| | | this.reservation = reservation; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-11-01. |
| | | */ |
| | | @Entity |
| | | public class IssueRisk extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private Long changeAssigneeCount; |
| | | private Long changeIssueStatusCount; |
| | | private String issueStatusIds; |
| | | |
| | | @OneToOne |
| | | @JoinColumn(name = "issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public IssueRisk(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Long getChangeAssigneeCount() { |
| | | return changeAssigneeCount; |
| | | } |
| | | |
| | | public void setChangeAssigneeCount(Long changeAssigneeCount) { |
| | | this.changeAssigneeCount = changeAssigneeCount; |
| | | } |
| | | |
| | | public Long getChangeIssueStatusCount() { |
| | | return changeIssueStatusCount; |
| | | } |
| | | |
| | | public void setChangeIssueStatusCount(Long changeIssueStatusCount) { |
| | | this.changeIssueStatusCount = changeIssueStatusCount; |
| | | } |
| | | |
| | | public String getIssueStatusIds() { |
| | | return issueStatusIds; |
| | | } |
| | | |
| | | public void setIssueStatusIds(String issueStatusIds) { |
| | | this.issueStatusIds = issueStatusIds; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class IssueSearch extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "user_id") |
| | | private User user; |
| | | |
| | | private String conditions; |
| | | |
| | | public IssueSearch(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | |
| | | public String getConditions() { |
| | | return conditions; |
| | | } |
| | | |
| | | public void setConditions(String conditions) { |
| | | this.conditions = conditions; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | |
| | | import kr.wisestone.owl.domain.enumType.IssueStatusType; |
| | | import org.hibernate.annotations.Type; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-03. |
| | | */ |
| | | @Entity |
| | | public class IssueStatus extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String color; |
| | | private Long position; // 기본 제공되는 이슈 상태에서 연결을 위해 사용 |
| | | |
| | | @Type(type = "yes_no") |
| | | private Boolean defaultYn = Boolean.FALSE; |
| | | |
| | | @Enumerated(EnumType.STRING) |
| | | private IssueStatusType issueStatusType; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToMany(mappedBy = "issueStatus", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<Issue> issues = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy="sourceIssueStatus", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<WorkflowTransition> sourceWorkflowTransitions = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy="targetIssueStatus", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<WorkflowTransition> targetWorkflowTransitions = new HashSet<>(); |
| | | |
| | | public IssueStatus() { |
| | | } |
| | | |
| | | public IssueStatus(Workspace workspace, String name, Boolean defaultYn, String color, IssueStatusType issueStatusType, Long position) { |
| | | this.workspace = workspace; |
| | | this.name = name; |
| | | this.defaultYn = defaultYn; |
| | | this.color = color; |
| | | this.issueStatusType = issueStatusType; |
| | | this.position = position; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Set<Issue> getIssues() { |
| | | return issues; |
| | | } |
| | | |
| | | public void setIssues(Set<Issue> issues) { |
| | | this.issues = issues; |
| | | } |
| | | |
| | | public String getColor() { |
| | | return color; |
| | | } |
| | | |
| | | public void setColor(String color) { |
| | | this.color = color; |
| | | } |
| | | |
| | | public IssueStatusType getIssueStatusType() { |
| | | return issueStatusType; |
| | | } |
| | | |
| | | public void setIssueStatusType(IssueStatusType issueStatusType) { |
| | | this.issueStatusType = issueStatusType; |
| | | } |
| | | |
| | | public Boolean getDefaultYn() { |
| | | return defaultYn; |
| | | } |
| | | |
| | | public void setDefaultYn(Boolean defaultYn) { |
| | | this.defaultYn = defaultYn; |
| | | } |
| | | |
| | | public Long getPosition() { |
| | | return position; |
| | | } |
| | | |
| | | public void setPosition(Long position) { |
| | | this.position = position; |
| | | } |
| | | |
| | | public Set<WorkflowTransition> getSourceWorkflowTransitions() { |
| | | return sourceWorkflowTransitions; |
| | | } |
| | | |
| | | public void setSourceWorkflowTransitions(Set<WorkflowTransition> sourceWorkflowTransitions) { |
| | | this.sourceWorkflowTransitions = sourceWorkflowTransitions; |
| | | } |
| | | |
| | | public Set<WorkflowTransition> getTargetWorkflowTransitions() { |
| | | return targetWorkflowTransitions; |
| | | } |
| | | |
| | | public void setTargetWorkflowTransitions(Set<WorkflowTransition> targetWorkflowTransitions) { |
| | | this.targetWorkflowTransitions = targetWorkflowTransitions; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2019-02-07. |
| | | */ |
| | | @Entity |
| | | public class IssueTableConfig extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String issueTableConfigs; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "user_id") |
| | | private User user; |
| | | |
| | | public IssueTableConfig(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getIssueTableConfigs() { |
| | | return issueTableConfigs; |
| | | } |
| | | |
| | | public void setIssueTableConfigs(String issueTableConfigs) { |
| | | this.issueTableConfigs = issueTableConfigs; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class IssueType extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String description; |
| | | private String color; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workflow_id") |
| | | private Workflow workflow; |
| | | |
| | | @OneToMany(mappedBy = "issueType", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueTypeCustomField> issueTypeCustomFields = new HashSet<>(); |
| | | |
| | | public IssueType(){} |
| | | |
| | | public IssueType(Workspace workspace, Workflow workflow, String name, String description, String color){ |
| | | this.workspace = workspace; |
| | | this.workflow = workflow; |
| | | this.name = name; |
| | | this.description = description; |
| | | this.color = color; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Workflow getWorkflow() { |
| | | return workflow; |
| | | } |
| | | |
| | | public void setWorkflow(Workflow workflow) { |
| | | this.workflow = workflow; |
| | | } |
| | | |
| | | public String getColor() { |
| | | return color; |
| | | } |
| | | |
| | | public void setColor(String color) { |
| | | this.color = color; |
| | | } |
| | | |
| | | public Set<IssueTypeCustomField> getIssueTypeCustomFields() { |
| | | return issueTypeCustomFields; |
| | | } |
| | | |
| | | public void setIssueTypeCustomFields(Set<IssueTypeCustomField> issueTypeCustomFields) { |
| | | this.issueTypeCustomFields = issueTypeCustomFields; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class IssueTypeCustomField extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String FIELD_OPTION_Y = "01"; // 필수로 사용 |
| | | public static final String FIELD_OPTION_N = "02"; // 옵션으로 사용 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String fieldOption; |
| | | private Integer position = 0; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "project_id") |
| | | private Project project; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "issue_type_id") |
| | | private IssueType issueType; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "custom_field_id") |
| | | private CustomField customField; |
| | | |
| | | @OneToMany(mappedBy = "issueTypeCustomField", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueCustomFieldValue> issueCustomFieldValues = new HashSet<>(); |
| | | |
| | | public IssueTypeCustomField(){} |
| | | |
| | | public IssueTypeCustomField(Project project, IssueType issueType, CustomField customField, String fieldOption){ |
| | | this.project = project; |
| | | this.issueType = issueType; |
| | | this.customField = customField; |
| | | this.fieldOption = fieldOption; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getFieldOption() { |
| | | return fieldOption; |
| | | } |
| | | |
| | | public void setFieldOption(String fieldOption) { |
| | | this.fieldOption = fieldOption; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public IssueType getIssueType() { |
| | | return issueType; |
| | | } |
| | | |
| | | public void setIssueType(IssueType issueType) { |
| | | this.issueType = issueType; |
| | | } |
| | | |
| | | public CustomField getCustomField() { |
| | | return customField; |
| | | } |
| | | |
| | | public void setCustomField(CustomField customField) { |
| | | this.customField = customField; |
| | | } |
| | | |
| | | public Set<IssueCustomFieldValue> getIssueCustomFieldValues() { |
| | | return issueCustomFieldValues; |
| | | } |
| | | |
| | | public void setIssueCustomFieldValues(Set<IssueCustomFieldValue> issueCustomFieldValues) { |
| | | this.issueCustomFieldValues = issueCustomFieldValues; |
| | | } |
| | | |
| | | public Integer getPosition() { |
| | | return position; |
| | | } |
| | | |
| | | public void setPosition(Integer position) { |
| | | this.position = position; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | @Entity |
| | | public class IssueUser extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "user_id") |
| | | private User user; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public IssueUser() { |
| | | } |
| | | |
| | | public IssueUser(Issue issue, User user) { |
| | | this.issue = issue; |
| | | this.user = user; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2019-02-28. |
| | | */ |
| | | @Entity |
| | | public class IssueVersion extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private Integer version; |
| | | private String content; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="project_id") |
| | | private Project project; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public IssueVersion() { |
| | | } |
| | | |
| | | public IssueVersion(Issue issue, Project project, Workspace workspace, String content) { |
| | | this.issue = issue; |
| | | this.project = project; |
| | | this.workspace = workspace; |
| | | this.content = content; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Integer getVersion() { |
| | | return version; |
| | | } |
| | | |
| | | public void setVersion(Integer version) { |
| | | this.version = version; |
| | | } |
| | | |
| | | public String getContent() { |
| | | return content; |
| | | } |
| | | |
| | | public void setContent(String content) { |
| | | this.content = content; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import org.hibernate.annotations.Type; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-13. |
| | | */ |
| | | @Entity |
| | | public class ManageUser extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch= FetchType.EAGER) // 스케쥴러에서 메일 전송을 위해 즉시 로딩 적용 |
| | | @JoinColumn(name="user_id") |
| | | private User user; |
| | | |
| | | @ManyToOne(fetch=FetchType.EAGER) // 스케쥴러에서 메일 전송을 위해 즉시 로딩 적용 |
| | | @JoinColumn(name="workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @Type(type = "yes_no") |
| | | private Boolean useYn = Boolean.FALSE; |
| | | |
| | | private Long disablePosition; |
| | | |
| | | public ManageUser() {} |
| | | |
| | | public ManageUser(User user, Workspace workspace, Boolean managerYn, Boolean useYn, Long disablePosition) { |
| | | this.user = user; |
| | | this.workspace = workspace; |
| | | this.useYn = useYn; |
| | | this.disablePosition = disablePosition; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Boolean getUseYn() { |
| | | return useYn; |
| | | } |
| | | |
| | | public void setUseYn(Boolean useYn) { |
| | | this.useYn = useYn; |
| | | } |
| | | |
| | | public Long getDisablePosition() { |
| | | return disablePosition; |
| | | } |
| | | |
| | | public void setDisablePosition(Long disablePosition) { |
| | | this.disablePosition = disablePosition; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.GenerationType; |
| | | import javax.persistence.Id; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-22 |
| | | */ |
| | | @Entity |
| | | public class Notice extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String title; |
| | | private String description; |
| | | |
| | | public Notice(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.math.BigInteger; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-13. |
| | | */ |
| | | @Entity |
| | | public class Payment extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String MONTH = "MONTH"; |
| | | public static final String YEAR = "YEAR"; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String type; |
| | | private Integer price; |
| | | private Integer buyUser; |
| | | |
| | | @OneToOne |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToOne(mappedBy = "payment", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private ReservationDisableUser reservationDisableUser; |
| | | |
| | | public Payment() { |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getType() { |
| | | return type; |
| | | } |
| | | |
| | | public void setType(String type) { |
| | | this.type = type; |
| | | } |
| | | |
| | | public Integer getPrice() { |
| | | return price; |
| | | } |
| | | |
| | | public void setPrice(Integer price) { |
| | | this.price = price; |
| | | } |
| | | |
| | | public Integer getBuyUser() { |
| | | return buyUser; |
| | | } |
| | | |
| | | public void setBuyUser(Integer buyUser) { |
| | | this.buyUser = buyUser; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public ReservationDisableUser getReservationDisableUser() { |
| | | return reservationDisableUser; |
| | | } |
| | | |
| | | public void setReservationDisableUser(ReservationDisableUser reservationDisableUser) { |
| | | this.reservationDisableUser = reservationDisableUser; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.service.impl.PaymentServiceImpl; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import org.apache.commons.text.StringEscapeUtils; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-13. |
| | | */ |
| | | @Entity |
| | | public class PaymentHistory extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String PAYMENT_RESULT_SUCCESS = "success"; |
| | | public static final String PAYMENT_RESULT_FAILED = "failed"; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String type; |
| | | private Integer price; |
| | | private Integer buyUser; |
| | | private String customerUid; |
| | | private String merchantUid; |
| | | private String paymentResult; |
| | | private String paymentResponse; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public PaymentHistory() { |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getType() { |
| | | return type; |
| | | } |
| | | |
| | | public void setType(String type) { |
| | | this.type = type; |
| | | } |
| | | |
| | | public Integer getPrice() { |
| | | return price; |
| | | } |
| | | |
| | | public void setPrice(Integer price) { |
| | | this.price = price; |
| | | } |
| | | |
| | | public Integer getBuyUser() { |
| | | return buyUser; |
| | | } |
| | | |
| | | public void setBuyUser(Integer buyUser) { |
| | | this.buyUser = buyUser; |
| | | } |
| | | |
| | | public String getCustomerUid() { |
| | | return customerUid; |
| | | } |
| | | |
| | | public void setCustomerUid(String customerUid) { |
| | | this.customerUid = customerUid; |
| | | } |
| | | |
| | | public String getMerchantUid() { |
| | | return merchantUid; |
| | | } |
| | | |
| | | public void setMerchantUid(String merchantUid) { |
| | | this.merchantUid = merchantUid; |
| | | } |
| | | |
| | | public String getPaymentResult() { |
| | | return paymentResult; |
| | | } |
| | | |
| | | public void setPaymentResult(String paymentResult) { |
| | | this.paymentResult = paymentResult; |
| | | } |
| | | |
| | | public String getPaymentResponse() { |
| | | return paymentResponse; |
| | | } |
| | | |
| | | public void setPaymentResponse(String paymentResponse) { |
| | | this.paymentResponse = paymentResponse; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public PaymentHistory bindPaymentResult(PaymentServiceImpl.RestClientResultObject resultObject) { |
| | | |
| | | if (resultObject.isValidResult()) { |
| | | this.setPaymentResult(PAYMENT_RESULT_SUCCESS); |
| | | this.setPaymentResponse(ConvertUtil.convertObjectToJson(resultObject.getResponse())); |
| | | } |
| | | else { |
| | | |
| | | this.setPaymentResult(PAYMENT_RESULT_FAILED); |
| | | |
| | | if (resultObject.isHttpRequestFailed()) { |
| | | this.setPaymentResponse(resultObject.getHttpStatus().getReasonPhrase()); |
| | | } |
| | | else if (resultObject.isIamportResultFailed()) { |
| | | this.setPaymentResponse(resultObject.getMessage()); |
| | | } |
| | | else if (resultObject.isIamportPaymentFailed()) { |
| | | if (StringUtils.hasText(resultObject.getMessage())) { |
| | | this.setPaymentResponse(resultObject.getMessage()); |
| | | } |
| | | else { |
| | | this.setPaymentResponse(StringEscapeUtils.unescapeJava(resultObject.getIamportFailReason())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return this; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | @Entity |
| | | public class Permission extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String ROLE_TYPE_USER = "01"; // 일반 사용자 권한 |
| | | public static final String ROLE_TYPE_WORKSPACE_MANAGER = "02"; // 워크스페이스 관리자 권한 |
| | | public static final String ROLE_TYPE_PROJECT_JOIN = "03"; // 프로젝트 참여자 권한 |
| | | public static final String ROLE_TYPE_PROJECT_MANAGER = "04"; // 프로젝트 관리자 권한 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String action; |
| | | private String roleType; |
| | | |
| | | @OneToMany(mappedBy="permission", cascade={CascadeType.ALL}) |
| | | private Set<SystemRolePermission> systemRolePermissions = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy="permission", cascade={CascadeType.ALL}) |
| | | private Set<ProjectRolePermission> projectRolePermissions = new HashSet<>(); |
| | | |
| | | public Permission() { |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getAction() { |
| | | return action; |
| | | } |
| | | |
| | | public void setAction(String action) { |
| | | this.action = action; |
| | | } |
| | | |
| | | public String getRoleType() { |
| | | return roleType; |
| | | } |
| | | |
| | | public void setRoleType(String roleType) { |
| | | this.roleType = roleType; |
| | | } |
| | | |
| | | public Set<SystemRolePermission> getSystemRolePermissions() { |
| | | return systemRolePermissions; |
| | | } |
| | | |
| | | public void setSystemRolePermissions(Set<SystemRolePermission> systemRolePermissions) { |
| | | this.systemRolePermissions = systemRolePermissions; |
| | | } |
| | | |
| | | public Set<ProjectRolePermission> getProjectRolePermissions() { |
| | | return projectRolePermissions; |
| | | } |
| | | |
| | | public void setProjectRolePermissions(Set<ProjectRolePermission> projectRolePermissions) { |
| | | this.projectRolePermissions = projectRolePermissions; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-03. |
| | | */ |
| | | @Entity |
| | | public class Priority extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private Integer position; |
| | | private String color; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToMany(mappedBy = "priority", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<Issue> issues = new HashSet<>(); |
| | | |
| | | public Priority() {} |
| | | |
| | | public Priority(String name, Integer position, String color, Workspace workspace) { |
| | | this.name = name; |
| | | this.position = position; |
| | | this.color = color; |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public Integer getPosition() { |
| | | return position; |
| | | } |
| | | |
| | | public void setPosition(Integer position) { |
| | | this.position = position; |
| | | } |
| | | |
| | | public String getColor() { |
| | | return color; |
| | | } |
| | | |
| | | public void setColor(String color) { |
| | | this.color = color; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Set<Issue> getIssues() { |
| | | return issues; |
| | | } |
| | | |
| | | public void setIssues(Set<Issue> issues) { |
| | | this.issues = issues; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import org.hibernate.annotations.Type; |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-12-30. |
| | | */ |
| | | @Entity |
| | | public class Project extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String PROJECT_READY = "01"; |
| | | public static final String PROJECT_OPEN = "02"; |
| | | public static final String PROJECT_CLOSE = "03"; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String projectKey; |
| | | private String description; |
| | | private String status; |
| | | private String startDate; |
| | | private String endDate; |
| | | @Type(type="yes_no") |
| | | private Boolean defaultYn = Boolean.FALSE; |
| | | |
| | | @Enumerated(EnumType.STRING) |
| | | private ProjectType projectType; |
| | | |
| | | @ManyToOne(fetch = FetchType.EAGER) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToMany(mappedBy = "project", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<Issue> issues = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "project", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueNumberGenerator> issueNumberGenerators = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "project", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueTypeCustomField> issueTypeCustomFields = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "project", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<ProjectRole> projectRoles = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "project", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<UserInviteProject> userInviteProjects = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "project", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<ProjectClosure> projectClosures = new HashSet<>(); |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getProjectKey() { |
| | | return projectKey; |
| | | } |
| | | |
| | | public void setProjectKey(String projectKey) { |
| | | this.projectKey = projectKey; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public String getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(String status) { |
| | | this.status = status; |
| | | } |
| | | |
| | | public String getStartDate() { |
| | | return startDate; |
| | | } |
| | | |
| | | public void setStartDate(String startDate) { |
| | | this.startDate = startDate; |
| | | } |
| | | |
| | | public String getEndDate() { |
| | | return endDate; |
| | | } |
| | | |
| | | public void setEndDate(String endDate) { |
| | | this.endDate = endDate; |
| | | } |
| | | |
| | | public Boolean getDefaultYn() { |
| | | return defaultYn; |
| | | } |
| | | |
| | | public void setDefaultYn(Boolean defaultYn) { |
| | | this.defaultYn = defaultYn; |
| | | } |
| | | |
| | | public ProjectType getProjectType() { |
| | | return projectType; |
| | | } |
| | | |
| | | public void setProjectType(ProjectType projectType) { |
| | | this.projectType = projectType; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Set<Issue> getIssues() { |
| | | return issues; |
| | | } |
| | | |
| | | public void setIssues(Set<Issue> issues) { |
| | | this.issues = issues; |
| | | } |
| | | |
| | | public Set<IssueNumberGenerator> getIssueNumberGenerators() { |
| | | return issueNumberGenerators; |
| | | } |
| | | |
| | | public void setIssueNumberGenerators(Set<IssueNumberGenerator> issueNumberGenerators) { |
| | | this.issueNumberGenerators = issueNumberGenerators; |
| | | } |
| | | |
| | | public Set<IssueTypeCustomField> getIssueTypeCustomFields() { |
| | | return issueTypeCustomFields; |
| | | } |
| | | |
| | | public void setIssueTypeCustomFields(Set<IssueTypeCustomField> issueTypeCustomFields) { |
| | | this.issueTypeCustomFields = issueTypeCustomFields; |
| | | } |
| | | |
| | | public Set<ProjectRole> getProjectRoles() { |
| | | return projectRoles; |
| | | } |
| | | |
| | | public void setProjectRoles(Set<ProjectRole> projectRoles) { |
| | | this.projectRoles = projectRoles; |
| | | } |
| | | |
| | | public Set<UserInviteProject> getUserInviteProjects() { |
| | | return userInviteProjects; |
| | | } |
| | | |
| | | public void setUserInviteProjects(Set<UserInviteProject> userInviteProjects) { |
| | | this.userInviteProjects = userInviteProjects; |
| | | } |
| | | |
| | | public Set<ProjectClosure> getProjectClosures() { |
| | | return projectClosures; |
| | | } |
| | | |
| | | public ProjectClosure getParentProjectClosure() { |
| | | if (this.projectClosures != null && this.projectClosures.size() > 0) { |
| | | Iterator<ProjectClosure> iter = this.projectClosures.iterator(); |
| | | return iter.next(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | public void setProjectClosures(Set<ProjectClosure> childProjects) { |
| | | this.projectClosures = childProjects; |
| | | } |
| | | |
| | | public void addParent(ProjectClosure project){ |
| | | projectClosures.add(project); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | @Entity |
| | | public class ProjectClosure extends BaseEntity implements Serializable { |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="project_id") |
| | | private Project project; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="parent_project_id") |
| | | private Project parentProject; |
| | | |
| | | public ProjectClosure(){} |
| | | |
| | | public ProjectClosure(Project project, Project parentProject){ |
| | | this.project = project; |
| | | this.parentProject = parentProject; |
| | | } |
| | | |
| | | public ProjectClosure(Project project) { |
| | | this.project = project; |
| | | this.parentProject = null; |
| | | } |
| | | |
| | | public Long getId() {return this.id; } |
| | | |
| | | public void setId(Long id) { this.id = id; } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public Project getParentProject() { |
| | | return parentProject; |
| | | } |
| | | |
| | | public void setParentProject(Project project) {this.parentProject = project; } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-12-30. |
| | | */ |
| | | @Entity |
| | | public class ProjectRole extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String TYPE_DEFAULT = "01"; // 일반 사용자 |
| | | public static final String TYPE_MANAGER = "02"; // 관리자 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String roleType; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="project_id") |
| | | private Project project; |
| | | |
| | | @OneToMany(mappedBy="projectRole", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<ProjectRoleUser> projectRoleUsers = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy="projectRole", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<ProjectRolePermission> projectRolePermissions = new HashSet<>(); |
| | | |
| | | public ProjectRole(){} |
| | | |
| | | public ProjectRole(Project project, String name, String roleType){ |
| | | this.project = project; |
| | | this.name = name; |
| | | this.roleType = roleType; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getRoleType() { |
| | | return roleType; |
| | | } |
| | | |
| | | public void setRoleType(String roleType) { |
| | | this.roleType = roleType; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public Set<ProjectRoleUser> getProjectRoleUsers() { |
| | | return projectRoleUsers; |
| | | } |
| | | |
| | | public void setProjectRoleUsers(Set<ProjectRoleUser> projectRoleUsers) { |
| | | this.projectRoleUsers = projectRoleUsers; |
| | | } |
| | | |
| | | public Set<ProjectRolePermission> getProjectRolePermissions() { |
| | | return projectRolePermissions; |
| | | } |
| | | |
| | | public void setProjectRolePermissions(Set<ProjectRolePermission> projectRolePermissions) { |
| | | this.projectRolePermissions = projectRolePermissions; |
| | | } |
| | | |
| | | public void addUser(User user) { |
| | | if (this.projectRoleUsers == null) { |
| | | this.projectRoleUsers = new HashSet<>(); |
| | | } |
| | | ProjectRoleUser projectRoleUser = new ProjectRoleUser(this, user); |
| | | |
| | | this.projectRoleUsers.add(projectRoleUser); |
| | | } |
| | | |
| | | public void removeProjectRole(User user) { |
| | | Iterator<ProjectRoleUser> iterator = this.projectRoleUsers.iterator(); |
| | | |
| | | while (iterator.hasNext()) { |
| | | ProjectRoleUser projectRoleUser = iterator.next(); |
| | | if (user.getId().equals(projectRoleUser.getUser().getId())) { |
| | | this.projectRoleUsers.remove(projectRoleUser); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-12-30. |
| | | */ |
| | | @Entity |
| | | public class ProjectRolePermission extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="project_role_id") |
| | | private ProjectRole projectRole; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name="permission_id") |
| | | private Permission permission; |
| | | |
| | | public ProjectRolePermission(){} |
| | | |
| | | public ProjectRolePermission(ProjectRole projectRole, Permission permission) { |
| | | this.projectRole = projectRole; |
| | | this.permission = permission; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public ProjectRole getProjectRole() { |
| | | return projectRole; |
| | | } |
| | | |
| | | public void setProjectRole(ProjectRole projectRole) { |
| | | this.projectRole = projectRole; |
| | | } |
| | | |
| | | public Permission getPermission() { |
| | | return permission; |
| | | } |
| | | |
| | | public void setPermission(Permission permission) { |
| | | this.permission = permission; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-12-30. |
| | | */ |
| | | @Entity |
| | | public class ProjectRoleUser extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name="project_role_id") |
| | | private ProjectRole projectRole; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name="user_id") |
| | | private User user; |
| | | |
| | | public ProjectRoleUser() { |
| | | } |
| | | |
| | | public ProjectRoleUser(ProjectRole projectRole, User user) { |
| | | this.projectRole = projectRole; |
| | | this.user = user; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public ProjectRole getProjectRole() { |
| | | return projectRole; |
| | | } |
| | | |
| | | public void setProjectRole(ProjectRole projectRole) { |
| | | this.projectRole = projectRole; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.GenerationType; |
| | | import javax.persistence.Id; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-22 |
| | | */ |
| | | @Entity |
| | | public class Qna extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String title; |
| | | private String description; |
| | | |
| | | public Qna(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-19. |
| | | */ |
| | | @Entity |
| | | public class ReservationDisableUser extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String userIds; |
| | | |
| | | @OneToOne |
| | | @JoinColumn(name = "payment_id") |
| | | private Payment payment; |
| | | |
| | | public ReservationDisableUser() {} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getUserIds() { |
| | | return userIds; |
| | | } |
| | | |
| | | public void setUserIds(String userIds) { |
| | | this.userIds = userIds; |
| | | } |
| | | |
| | | public Payment getPayment() { |
| | | return payment; |
| | | } |
| | | |
| | | public void setPayment(Payment payment) { |
| | | this.payment = payment; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-15. |
| | | */ |
| | | @Entity |
| | | public class Severity extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private Integer position; |
| | | private String color; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToMany(mappedBy = "severity", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<Issue> issues = new HashSet<>(); |
| | | |
| | | public Severity(){} |
| | | |
| | | public Severity(String name, Integer position, String color, Workspace workspace){ |
| | | this.name = name; |
| | | this.position = position; |
| | | this.color = color; |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public Integer getPosition() { |
| | | return position; |
| | | } |
| | | |
| | | public void setPosition(Integer position) { |
| | | this.position = position; |
| | | } |
| | | |
| | | public String getColor() { |
| | | return color; |
| | | } |
| | | |
| | | public void setColor(String color) { |
| | | this.color = color; |
| | | } |
| | | |
| | | public Set<Issue> getIssues() { |
| | | return issues; |
| | | } |
| | | |
| | | public void setIssues(Set<Issue> issues) { |
| | | this.issues = issues; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.EmailType; |
| | | import org.hibernate.annotations.Type; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-14. |
| | | */ |
| | | @Entity |
| | | public class SystemEmail extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String sendAddress; |
| | | @Enumerated(EnumType.STRING) |
| | | private EmailType emailType; |
| | | private String parameter; |
| | | @Type(type = "yes_no") |
| | | private Boolean sendYn = Boolean.FALSE; // N : 발송 대기, Y : 발송 완료 |
| | | |
| | | public SystemEmail() {} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getSendAddress() { |
| | | return sendAddress; |
| | | } |
| | | |
| | | public void setSendAddress(String sendAddress) { |
| | | this.sendAddress = sendAddress; |
| | | } |
| | | |
| | | public EmailType getEmailType() { |
| | | return emailType; |
| | | } |
| | | |
| | | public void setEmailType(EmailType emailType) { |
| | | this.emailType = emailType; |
| | | } |
| | | |
| | | public String getParameter() { |
| | | return parameter; |
| | | } |
| | | |
| | | public void setParameter(String parameter) { |
| | | this.parameter = parameter; |
| | | } |
| | | |
| | | public Boolean getSendYn() { |
| | | return sendYn; |
| | | } |
| | | |
| | | public void setSendYn(Boolean sendYn) { |
| | | this.sendYn = sendYn; |
| | | } |
| | | } |
New file |
| | |
| | | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | |
| | | import com.google.common.collect.Lists; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.*; |
| | | |
| | | @Entity |
| | | public class SystemRole extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String roleType; |
| | | |
| | | @OneToMany(mappedBy="systemRole", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<SystemRoleUser> systemRoleUsers = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy="systemRole", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<SystemRolePermission> systemRolePermissions = new HashSet<>(); |
| | | |
| | | public SystemRole() { |
| | | } |
| | | |
| | | public Long getId() { |
| | | return this.id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return this.name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public Set<SystemRoleUser> getSystemRoleUsers() { |
| | | return this.systemRoleUsers; |
| | | } |
| | | |
| | | public List<User> getUsers() { |
| | | List<User> users = Lists.newArrayList(); |
| | | |
| | | Iterator<SystemRoleUser> iterator = this.systemRoleUsers.iterator(); |
| | | while (iterator.hasNext()) { |
| | | users.add(iterator.next().getUser()); |
| | | } |
| | | |
| | | return users; |
| | | } |
| | | |
| | | public void setSystemRoleUsers(Set<SystemRoleUser> systemRoleUsers) { |
| | | this.systemRoleUsers = systemRoleUsers; |
| | | } |
| | | |
| | | public Set<SystemRolePermission> getSystemRolePermissions() { |
| | | return this.systemRolePermissions; |
| | | } |
| | | |
| | | public List<Permission> getPermissions() { |
| | | List<Permission> permissions = new ArrayList<Permission>(); |
| | | |
| | | Iterator<SystemRolePermission> iterator = this.systemRolePermissions.iterator(); |
| | | while (iterator.hasNext()) { |
| | | permissions.add(iterator.next().getPermission()); |
| | | } |
| | | |
| | | return permissions; |
| | | } |
| | | |
| | | public void setSystemRolePermissions(Set<SystemRolePermission> systemRolePermissions) { |
| | | this.systemRolePermissions = systemRolePermissions; |
| | | } |
| | | |
| | | public void addSystemRolePermission(SystemRolePermission systemRolePermission) { |
| | | if (this.systemRolePermissions == null) { |
| | | this.systemRolePermissions = new HashSet<>(); |
| | | } |
| | | |
| | | this.systemRolePermissions.add(systemRolePermission); |
| | | } |
| | | |
| | | public void removeSystemRolePermission(SystemRolePermission systemRolePermission) { |
| | | this.systemRolePermissions.remove(systemRolePermission); |
| | | } |
| | | |
| | | public void addSystemRoleUser(SystemRoleUser systemRoleUser) { |
| | | if (this.systemRoleUsers == null) { |
| | | this.systemRoleUsers = new HashSet<>(); |
| | | } |
| | | |
| | | this.systemRoleUsers.add(systemRoleUser); |
| | | } |
| | | |
| | | public String getRoleType() { |
| | | return roleType; |
| | | } |
| | | |
| | | public void setRoleType(String roleType) { |
| | | this.roleType = roleType; |
| | | } |
| | | |
| | | public void removeSystemRoleUser(SystemRoleUser systemRoleUser) { |
| | | this.systemRoleUsers.remove(systemRoleUser); |
| | | } |
| | | |
| | | public boolean contains(User user) { |
| | | for (SystemRoleUser systemRoleUser : this.systemRoleUsers) { |
| | | if (user.getId().equals(systemRoleUser.getUser().getId())) { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | public boolean contains(Long userId) { |
| | | for (SystemRoleUser systemRoleUser : this.systemRoleUsers) { |
| | | if (userId.equals(systemRoleUser.getUser().getId())) { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + (this.id == null ? 0 : this.id.hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public boolean equals(Object obj) { |
| | | if (this == obj) { |
| | | return true; |
| | | } |
| | | if (obj == null) { |
| | | return false; |
| | | } |
| | | if (this.getClass() != obj.getClass()) { |
| | | return false; |
| | | } |
| | | SystemRole other = (SystemRole) obj; |
| | | if (this.id == null) { |
| | | if (other.id != null) { |
| | | return false; |
| | | } |
| | | } else if (!this.id.equals(other.id)) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append("SystemRole ["); |
| | | if (this.id != null) { |
| | | builder.append("id="); |
| | | builder.append(this.id); |
| | | builder.append(", "); |
| | | } |
| | | if (this.name != null) { |
| | | builder.append("name="); |
| | | builder.append(this.name); |
| | | builder.append(", "); |
| | | } |
| | | |
| | | if (this.systemRoleUsers != null) { |
| | | builder.append("systemRoleUsers="); |
| | | builder.append(this.systemRoleUsers); |
| | | builder.append(", "); |
| | | } |
| | | if (this.systemRolePermissions != null) { |
| | | builder.append("systemRolePermissions="); |
| | | builder.append(this.systemRolePermissions); |
| | | } |
| | | builder.append("]"); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | public void addUser(User user) { |
| | | if (this.systemRoleUsers == null) { |
| | | this.systemRoleUsers = new HashSet<>(); |
| | | } |
| | | |
| | | SystemRoleUser systemRoleUser = new SystemRoleUser(); |
| | | systemRoleUser.setSystemRole(this); |
| | | systemRoleUser.setUser(user); |
| | | |
| | | this.systemRoleUsers.add(systemRoleUser); |
| | | } |
| | | |
| | | public void removeUser(User user) { |
| | | for (SystemRoleUser systemRoleUser : this.systemRoleUsers) { |
| | | if (user.getId().equals(systemRoleUser.getUser().getId())) { |
| | | this.systemRoleUsers.remove(systemRoleUser); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void addPermission(Permission permission) { |
| | | SystemRolePermission systemRolePermission = new SystemRolePermission(); |
| | | systemRolePermission.setSystemRole(this); |
| | | systemRolePermission.setPermission(permission); |
| | | |
| | | systemRolePermissions.add(systemRolePermission); |
| | | } |
| | | } |
New file |
| | |
| | | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | @Entity |
| | | public class SystemRolePermission extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name="system_role_id") |
| | | private SystemRole systemRole; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name="permission_id") |
| | | private Permission permission; |
| | | |
| | | public SystemRolePermission() { |
| | | } |
| | | |
| | | public SystemRolePermission(SystemRole systemRole, Permission permission) { |
| | | this.systemRole = systemRole; |
| | | this.permission = permission; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | /** |
| | | * @return systemRole |
| | | */ |
| | | public SystemRole getSystemRole() { |
| | | return this.systemRole; |
| | | } |
| | | |
| | | /** |
| | | * @param systemRole |
| | | */ |
| | | public void setSystemRole(SystemRole systemRole) { |
| | | this.systemRole = systemRole; |
| | | } |
| | | |
| | | /** |
| | | * @return permission |
| | | */ |
| | | public Permission getPermission() { |
| | | return this.permission; |
| | | } |
| | | |
| | | /** |
| | | * @param permission |
| | | */ |
| | | public void setPermission(Permission permission) { |
| | | this.permission = permission; |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((id == null) ? 0 : id.hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public boolean equals(Object obj) { |
| | | if (this == obj) |
| | | return true; |
| | | if (obj == null) |
| | | return false; |
| | | if (getClass() != obj.getClass()) |
| | | return false; |
| | | SystemRolePermission other = (SystemRolePermission) obj; |
| | | if (id == null) { |
| | | if (other.id != null) |
| | | return false; |
| | | } else if (!id.equals(other.id)) |
| | | return false; |
| | | return true; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | @Entity |
| | | public class SystemRoleUser extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "system_role_id") |
| | | private SystemRole systemRole; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "user_id") |
| | | private User user; |
| | | |
| | | public SystemRoleUser() { |
| | | } |
| | | |
| | | public SystemRoleUser(SystemRole systemRole, User user) { |
| | | this.systemRole = systemRole; |
| | | this.user = user; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public SystemRole getSystemRole() { |
| | | return systemRole; |
| | | } |
| | | |
| | | public void setSystemRole(SystemRole systemRole) { |
| | | this.systemRole = systemRole; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.SocialType; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import org.springframework.security.core.GrantedAuthority; |
| | | import org.springframework.security.core.userdetails.UserDetails; |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.security.Principal; |
| | | import java.util.*; |
| | | |
| | | @Entity |
| | | public class User extends BaseEntity implements UserDetails, Principal, Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String USER_STATUS_ACTIVE = "01"; // 사용자 활성 |
| | | public static final String USER_STATUS_DEL = "02"; // 사용자 탈퇴 |
| | | public static final String DEFAULT_PROFILE = "assets/images/default_profile.png"; // 기본 프로필 |
| | | public static final String DEFAULT_RESERVATION_NOTIFY_TIME = "09:00"; // 기본 이메일 알림 예정 시간 |
| | | public static final String DEFAULT_LANGUAGE = "ko"; // 기본 언어 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String account; |
| | | private String password; |
| | | private String status; |
| | | private String phone; |
| | | private String profile; |
| | | private String awsKey; |
| | | @Enumerated(EnumType.STRING) |
| | | private SocialType socialType; |
| | | private Long lastWorkspaceId; |
| | | private Long lastProjectId; |
| | | private Date lastLoginDate; |
| | | private String reservationNotifyTime; // 이메일 알림 시간 예정 |
| | | private String language; |
| | | private Integer permission; |
| | | private String licensekey; |
| | | |
| | | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<SystemRoleUser> systemRoleUsers = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<ProjectRoleUser> projectRoleUsers = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueUser> issueUsers = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<UserLikeIssue> userLikeIssues = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<UserWorkspace> userWorkspaces = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueSearch> issueSearches = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueTableConfig> issueTableConfigs = new HashSet<>(); |
| | | |
| | | public User() { |
| | | } |
| | | |
| | | public User(Long id, String name, String account) { |
| | | this.id = id; |
| | | this.name = name; |
| | | this.account = account; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getAccount() { |
| | | return account; |
| | | } |
| | | |
| | | public void setAccount(String account) { |
| | | this.account = account; |
| | | } |
| | | |
| | | public String getPassword() { |
| | | return password; |
| | | } |
| | | |
| | | public void setPassword(String password) { |
| | | this.password = password; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getProfile() { |
| | | return profile; |
| | | } |
| | | |
| | | public void setProfile(String profile) { |
| | | this.profile = profile; |
| | | } |
| | | |
| | | public String getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(String status) { |
| | | this.status = status; |
| | | } |
| | | |
| | | public SocialType getSocialType() { |
| | | return socialType; |
| | | } |
| | | |
| | | public void setSocialType(SocialType socialType) { |
| | | this.socialType = socialType; |
| | | } |
| | | |
| | | public String getPhone() { |
| | | return phone; |
| | | } |
| | | |
| | | public void setPhone(String phone) { |
| | | this.phone = phone; |
| | | } |
| | | |
| | | public Long getLastWorkspaceId() { |
| | | return lastWorkspaceId; |
| | | } |
| | | |
| | | public Long getLastProjectId() {return lastProjectId; } |
| | | |
| | | public void setLastProjectId(Long lastProjectId) { |
| | | this.lastProjectId = lastProjectId; |
| | | } |
| | | |
| | | public String getAwsKey() { |
| | | return awsKey; |
| | | } |
| | | |
| | | public void setAwsKey(String awsKey) { |
| | | this.awsKey = awsKey; |
| | | } |
| | | |
| | | public void setLastWorkspaceId(Long lastWorkspaceId) { |
| | | this.lastWorkspaceId = lastWorkspaceId; |
| | | } |
| | | |
| | | public Set<SystemRoleUser> getSystemRoleUsers() { |
| | | return systemRoleUsers; |
| | | } |
| | | |
| | | public Set<IssueSearch> getIssueSearches() { |
| | | return issueSearches; |
| | | } |
| | | |
| | | public void setIssueSearches(Set<IssueSearch> issueSearches) { |
| | | this.issueSearches = issueSearches; |
| | | } |
| | | |
| | | public void setSystemRoleUsers(Set<SystemRoleUser> systemRoleUsers) { |
| | | this.systemRoleUsers = systemRoleUsers; |
| | | } |
| | | |
| | | public void addSystemRole(SystemRole systemRole) { |
| | | if (this.systemRoleUsers == null) { |
| | | this.systemRoleUsers = new HashSet<>(); |
| | | } |
| | | SystemRoleUser systemRoleUser = new SystemRoleUser(systemRole, this); |
| | | |
| | | this.systemRoleUsers.add(systemRoleUser); |
| | | } |
| | | |
| | | public Set<ProjectRoleUser> getProjectRoleUsers() { |
| | | return projectRoleUsers; |
| | | } |
| | | |
| | | public void setProjectRoleUsers(Set<ProjectRoleUser> projectRoleUsers) { |
| | | this.projectRoleUsers = projectRoleUsers; |
| | | } |
| | | |
| | | public void addProjectRole(ProjectRole projectRole) { |
| | | if (this.projectRoleUsers == null) { |
| | | this.projectRoleUsers = new HashSet<>(); |
| | | } |
| | | ProjectRoleUser projectRoleUser = new ProjectRoleUser(projectRole, this); |
| | | |
| | | this.projectRoleUsers.add(projectRoleUser); |
| | | } |
| | | |
| | | public void removeProjectRole(ProjectRole projectRole) { |
| | | Iterator<ProjectRoleUser> iterator = this.projectRoleUsers.iterator(); |
| | | |
| | | while (iterator.hasNext()) { |
| | | ProjectRoleUser projectRoleUser = iterator.next(); |
| | | if (projectRole.getId().equals(projectRoleUser.getProjectRole().getId())) { |
| | | this.projectRoleUsers.remove(projectRoleUser); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | public Set<IssueUser> getIssueUsers() { |
| | | return issueUsers; |
| | | } |
| | | |
| | | public void setIssueUsers(Set<IssueUser> issueUsers) { |
| | | this.issueUsers = issueUsers; |
| | | } |
| | | |
| | | public void addIssue(Issue issue) { |
| | | if (this.issueUsers == null) { |
| | | this.issueUsers = new HashSet<>(); |
| | | } |
| | | IssueUser issueUser = new IssueUser(issue, this); |
| | | |
| | | this.issueUsers.add(issueUser); |
| | | } |
| | | |
| | | public void removeIssue(Issue issue) { |
| | | Iterator<IssueUser> iterator = this.issueUsers.iterator(); |
| | | |
| | | while (iterator.hasNext()) { |
| | | IssueUser issueUser = iterator.next(); |
| | | if (issue.getId().equals(issueUser.getIssue().getId())) { |
| | | this.issueUsers.remove(issueUser); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | public Set<UserWorkspace> getUserWorkspaces() { |
| | | return userWorkspaces; |
| | | } |
| | | |
| | | public void setUserWorkspaces(Set<UserWorkspace> userWorkspaces) { |
| | | this.userWorkspaces = userWorkspaces; |
| | | } |
| | | |
| | | public Set<UserLikeIssue> getUserLikeIssues() { |
| | | return userLikeIssues; |
| | | } |
| | | |
| | | public void setUserLikeIssues(Set<UserLikeIssue> userLikeIssues) { |
| | | this.userLikeIssues = userLikeIssues; |
| | | } |
| | | |
| | | public String getReservationNotifyTime() { |
| | | return reservationNotifyTime; |
| | | } |
| | | |
| | | public void setReservationNotifyTime(String reservationNotifyTime) { |
| | | this.reservationNotifyTime = reservationNotifyTime; |
| | | } |
| | | |
| | | public Set<IssueTableConfig> getIssueTableConfigs() { |
| | | return issueTableConfigs; |
| | | } |
| | | |
| | | public void setIssueTableConfigs(Set<IssueTableConfig> issueTableConfigs) { |
| | | this.issueTableConfigs = issueTableConfigs; |
| | | } |
| | | |
| | | public String getLanguage() { |
| | | return language; |
| | | } |
| | | |
| | | public void setLanguage(String language) { |
| | | this.language = language; |
| | | } |
| | | |
| | | public Integer getPermission() { |
| | | return permission; |
| | | } |
| | | |
| | | public void setPermission(Integer permission) { |
| | | this.permission = permission; |
| | | } |
| | | |
| | | public String getLicensekey() { |
| | | return licensekey; |
| | | } |
| | | |
| | | public void setLicensekey(String licensekey) { |
| | | this.licensekey = licensekey; |
| | | } |
| | | |
| | | @Override |
| | | public Collection<? extends GrantedAuthority> getAuthorities() { |
| | | // TODO Auto-generated method stub |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public String getUsername() { |
| | | return this.account; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isAccountNonExpired() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isAccountNonLocked() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isCredentialsNonExpired() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isEnabled() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((this.account == null) ? 0 : this.account.hashCode()); |
| | | result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public boolean equals(Object obj) { |
| | | if (this == obj) { |
| | | return true; |
| | | } |
| | | if (obj == null) { |
| | | return false; |
| | | } |
| | | if (getClass() != obj.getClass()) { |
| | | return false; |
| | | } |
| | | User other = (User) obj; |
| | | if (this.account == null) { |
| | | if (other.account != null) { |
| | | return false; |
| | | } |
| | | } |
| | | else if (!this.account.equals(other.account)) { |
| | | return false; |
| | | } |
| | | if (this.id == null) { |
| | | if (other.id != null) { |
| | | return false; |
| | | } |
| | | } |
| | | else if (!this.id.equals(other.id)) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public void setLastLoginDate(Date date) { this.lastLoginDate = date; } |
| | | public Date getLastLoginDate() { return this.lastLoginDate; } |
| | | |
| | | /*@Override |
| | | public String toString() { |
| | | return CommonUtil.decryptAES128(this.account); |
| | | }*/ |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.SocialType; |
| | | import org.springframework.security.core.userdetails.UserDetails; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.security.Principal; |
| | | |
| | | @Entity |
| | | public class UserHistory extends BaseEntity implements Serializable { |
| | | |
| | | public static final String HISTORY_LOGIN = "LOGIN"; |
| | | public static final String HISTORY_LOGOUT = "LOGOUT"; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String historyType; |
| | | |
| | | public Long getId(){ return this.id; } |
| | | |
| | | public void setId(Long id) { this.id = id; } |
| | | |
| | | public String getHistoryType() { return this.historyType; } |
| | | |
| | | public void setHistoryType(String historyType) { this.historyType = historyType; } |
| | | |
| | | public UserHistory() { } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-14. |
| | | */ |
| | | @Entity |
| | | public class UserInvite extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public static final String WORKSPACE_JOIN_READY = "01"; // 초대중 |
| | | public static final String WORKSPACE_JOIN_COMPLETE = "02"; // 가입 완료 |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String email; |
| | | private String status; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToMany(mappedBy="userInvite", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<UserInviteProject> userInviteProjects = new HashSet<>(); |
| | | |
| | | public UserInvite() { |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getEmail() { |
| | | return email; |
| | | } |
| | | |
| | | public void setEmail(String email) { |
| | | this.email = email; |
| | | } |
| | | |
| | | public String getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(String status) { |
| | | this.status = status; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Set<UserInviteProject> getUserInviteProjects() { |
| | | return userInviteProjects; |
| | | } |
| | | |
| | | public void setUserInviteProjects(Set<UserInviteProject> userInviteProjects) { |
| | | this.userInviteProjects = userInviteProjects; |
| | | } |
| | | |
| | | public void removeUserInviteProject() { |
| | | Iterator<UserInviteProject> iterator = this.userInviteProjects.iterator(); |
| | | |
| | | while (iterator.hasNext()) { |
| | | this.userInviteProjects.remove(iterator.next()); |
| | | } |
| | | } |
| | | |
| | | public void addUserInviteProjects(UserInviteProject userInviteProject) { |
| | | this.userInviteProjects.add(userInviteProject); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-15. |
| | | */ |
| | | @Entity |
| | | public class UserInviteProject extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="user_invite_id") |
| | | private UserInvite userInvite; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name="project_id") |
| | | private Project project; |
| | | |
| | | public UserInviteProject(){} |
| | | |
| | | public UserInviteProject(UserInvite userInvite, Project project){ |
| | | this.userInvite = userInvite; |
| | | this.project = project; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public UserInvite getUserInvite() { |
| | | return userInvite; |
| | | } |
| | | |
| | | public void setUserInvite(UserInvite userInvite) { |
| | | this.userInvite = userInvite; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class UserLikeIssue extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "user_id") |
| | | private User user; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "issue_id") |
| | | private Issue issue; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | public UserLikeIssue(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | |
| | | public Issue getIssue() { |
| | | return issue; |
| | | } |
| | | |
| | | public void setIssue(Issue issue) { |
| | | this.issue = issue; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.GeneratedValue; |
| | | import javax.persistence.GenerationType; |
| | | import javax.persistence.Id; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-11-19. |
| | | */ |
| | | @Entity |
| | | public class UserWithDraw extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String account; |
| | | |
| | | public UserWithDraw(){} |
| | | |
| | | public UserWithDraw(String account){ |
| | | this.account = account; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getAccount() { |
| | | return account; |
| | | } |
| | | |
| | | public void setAccount(String account) { |
| | | this.account = account; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import org.hibernate.annotations.Type; |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-13. |
| | | */ |
| | | @Entity |
| | | public class UserWorkspace extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch= FetchType.EAGER) // 스케쥴러에서 메일 전송을 위해 즉시 로딩 적용 |
| | | @JoinColumn(name="user_id") |
| | | private User user; |
| | | |
| | | @ManyToOne(fetch=FetchType.EAGER) // 스케쥴러에서 메일 전송을 위해 즉시 로딩 적용 |
| | | @JoinColumn(name="workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @Type(type = "yes_no") |
| | | private Boolean managerYn = Boolean.FALSE; |
| | | |
| | | @Type(type = "yes_no") |
| | | private Boolean useYn = Boolean.FALSE; |
| | | |
| | | private Long disablePosition; |
| | | |
| | | public UserWorkspace() {} |
| | | |
| | | public UserWorkspace(User user, Workspace workspace, Boolean managerYn, Boolean useYn, Long disablePosition) { |
| | | this.user = user; |
| | | this.workspace = workspace; |
| | | this.managerYn = managerYn; |
| | | this.useYn = useYn; |
| | | this.disablePosition = disablePosition; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public User getUser() { |
| | | return user; |
| | | } |
| | | |
| | | public void setUser(User user) { |
| | | this.user = user; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Boolean getManagerYn() { |
| | | return managerYn; |
| | | } |
| | | |
| | | public void setManagerYn(Boolean managerYn) { |
| | | this.managerYn = managerYn; |
| | | } |
| | | |
| | | public Boolean getUseYn() { |
| | | return useYn; |
| | | } |
| | | |
| | | public void setUseYn(Boolean useYn) { |
| | | this.useYn = useYn; |
| | | } |
| | | |
| | | public Long getDisablePosition() { |
| | | return disablePosition; |
| | | } |
| | | |
| | | public void setDisablePosition(Long disablePosition) { |
| | | this.disablePosition = disablePosition; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class Workflow extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private String description; |
| | | |
| | | @Enumerated(EnumType.STRING) |
| | | private ProjectType projectType; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workspace_id") |
| | | private Workspace workspace; |
| | | |
| | | @OneToMany(mappedBy = "workflow", cascade = {CascadeType.ALL}) |
| | | private Set<IssueType> issueTypes = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workflow", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<WorkflowTransition> workflowTransitions = new HashSet<>(); |
| | | |
| | | public Workflow(){} |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Workspace getWorkspace() { |
| | | return workspace; |
| | | } |
| | | |
| | | public void setWorkspace(Workspace workspace) { |
| | | this.workspace = workspace; |
| | | } |
| | | |
| | | public Set<IssueType> getIssueTypes() { |
| | | return issueTypes; |
| | | } |
| | | |
| | | public void setIssueTypes(Set<IssueType> issueTypes) { |
| | | this.issueTypes = issueTypes; |
| | | } |
| | | |
| | | public Set<WorkflowTransition> getWorkflowTransitions() { |
| | | return workflowTransitions; |
| | | } |
| | | |
| | | public void setWorkflowTransitions(Set<WorkflowTransition> workflowTransitions) { |
| | | this.workflowTransitions = workflowTransitions; |
| | | } |
| | | |
| | | public ProjectType getProjectType() { |
| | | return projectType; |
| | | } |
| | | |
| | | public void setProjectType(ProjectType projectType) { |
| | | this.projectType = projectType; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import org.hibernate.annotations.Type; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-03. |
| | | */ |
| | | @Entity |
| | | public class WorkflowStatus extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy=GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | @Type(type="yes_no") |
| | | private Boolean firstYn = Boolean.FALSE; |
| | | @Type(type="yes_no") |
| | | private Boolean lastYn = Boolean.FALSE; |
| | | private String color; |
| | | private Long progress; |
| | | private Long position; |
| | | |
| | | @ManyToOne(fetch= FetchType.LAZY) |
| | | @JoinColumn(name="project_id") |
| | | private Project project; |
| | | |
| | | @OneToMany(mappedBy="workflowStatus", cascade={CascadeType.ALL}, orphanRemoval=true) |
| | | private Set<Issue> tasks = new HashSet<Issue>(); |
| | | |
| | | public WorkflowStatus() {} |
| | | |
| | | public WorkflowStatus(Project project, String name, Boolean firstYn, Boolean lastYn, String color, Long progress, Long position) { |
| | | this.project = project; |
| | | this.name = name; |
| | | this.firstYn = firstYn; |
| | | this.lastYn = lastYn; |
| | | this.color = color; |
| | | this.progress = progress; |
| | | this.position = position; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public Boolean getFirstYn() { |
| | | return firstYn; |
| | | } |
| | | |
| | | public void setFirstYn(Boolean firstYn) { |
| | | this.firstYn = firstYn; |
| | | } |
| | | |
| | | public Boolean getLastYn() { |
| | | return lastYn; |
| | | } |
| | | |
| | | public void setLastYn(Boolean lastYn) { |
| | | this.lastYn = lastYn; |
| | | } |
| | | |
| | | public Long getProgress() { |
| | | return progress; |
| | | } |
| | | |
| | | public void setProgress(Long progress) { |
| | | this.progress = progress; |
| | | } |
| | | |
| | | public Long getPosition() { |
| | | return position; |
| | | } |
| | | |
| | | public void setPosition(Long position) { |
| | | this.position = position; |
| | | } |
| | | |
| | | public Project getProject() { |
| | | return project; |
| | | } |
| | | |
| | | public void setProject(Project project) { |
| | | this.project = project; |
| | | } |
| | | |
| | | public Set<Issue> getTasks() { |
| | | return tasks; |
| | | } |
| | | |
| | | public void setTasks(Set<Issue> tasks) { |
| | | this.tasks = tasks; |
| | | } |
| | | |
| | | public String getColor() { |
| | | return color; |
| | | } |
| | | |
| | | public void setColor(String color) { |
| | | this.color = color; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import org.hibernate.annotations.Type; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-07. |
| | | */ |
| | | @Entity |
| | | public class WorkflowTransition extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "workflow_id") |
| | | private Workflow workflow; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "source_issue_status_id") |
| | | private IssueStatus sourceIssueStatus; |
| | | |
| | | @ManyToOne(fetch = FetchType.LAZY) |
| | | @JoinColumn(name = "target_issue_status_id") |
| | | private IssueStatus targetIssueStatus; |
| | | |
| | | private Long sourceX; |
| | | private Long sourceY; |
| | | private Long targetX; |
| | | private Long targetY; |
| | | private Long correctX; |
| | | private Long correctY; |
| | | @Type(type="yes_no") |
| | | private Boolean direct = Boolean.FALSE; |
| | | |
| | | public WorkflowTransition(){} |
| | | |
| | | public WorkflowTransition(Workflow workflow, IssueStatus sourceIssueStatus, IssueStatus targetIssueStatus, Long sourceX, Long sourceY, Long targetX, Long targetY, Long correctX, Long correctY){ |
| | | this.workflow = workflow; |
| | | this.sourceIssueStatus = sourceIssueStatus; |
| | | this.targetIssueStatus = targetIssueStatus; |
| | | this.sourceX = sourceX; |
| | | this.sourceY = sourceY; |
| | | this.targetX = targetX; |
| | | this.targetY = targetY; |
| | | this.correctX = correctX; |
| | | this.correctY = correctY; |
| | | } |
| | | |
| | | public WorkflowTransition(Workflow workflow, IssueStatus sourceIssueStatus, IssueStatus targetIssueStatus, Long sourceX, Long sourceY, Long targetX, Long targetY, Long correctX, Long correctY, Boolean direct){ |
| | | this.workflow = workflow; |
| | | this.sourceIssueStatus = sourceIssueStatus; |
| | | this.targetIssueStatus = targetIssueStatus; |
| | | this.sourceX = sourceX; |
| | | this.sourceY = sourceY; |
| | | this.targetX = targetX; |
| | | this.targetY = targetY; |
| | | this.correctX = correctX; |
| | | this.correctY = correctY; |
| | | this.direct = direct; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Workflow getWorkflow() { |
| | | return workflow; |
| | | } |
| | | |
| | | public void setWorkflow(Workflow workflow) { |
| | | this.workflow = workflow; |
| | | } |
| | | |
| | | public IssueStatus getSourceIssueStatus() { |
| | | return sourceIssueStatus; |
| | | } |
| | | |
| | | public void setSourceIssueStatus(IssueStatus sourceIssueStatus) { |
| | | this.sourceIssueStatus = sourceIssueStatus; |
| | | } |
| | | |
| | | public IssueStatus getTargetIssueStatus() { |
| | | return targetIssueStatus; |
| | | } |
| | | |
| | | public void setTargetIssueStatus(IssueStatus targetIssueStatus) { |
| | | this.targetIssueStatus = targetIssueStatus; |
| | | } |
| | | |
| | | public Long getSourceX() { |
| | | return sourceX; |
| | | } |
| | | |
| | | public void setSourceX(Long sourceX) { |
| | | this.sourceX = sourceX; |
| | | } |
| | | |
| | | public Long getSourceY() { |
| | | return sourceY; |
| | | } |
| | | |
| | | public void setSourceY(Long sourceY) { |
| | | this.sourceY = sourceY; |
| | | } |
| | | |
| | | public Long getTargetX() { |
| | | return targetX; |
| | | } |
| | | |
| | | public void setTargetX(Long targetX) { |
| | | this.targetX = targetX; |
| | | } |
| | | |
| | | public Long getTargetY() { |
| | | return targetY; |
| | | } |
| | | |
| | | public void setTargetY(Long targetY) { |
| | | this.targetY = targetY; |
| | | } |
| | | |
| | | public Long getCorrectX() { |
| | | return correctX; |
| | | } |
| | | |
| | | public void setCorrectX(Long correctX) { |
| | | this.correctX = correctX; |
| | | } |
| | | |
| | | public Long getCorrectY() { |
| | | return correctY; |
| | | } |
| | | |
| | | public void setCorrectY(Long correctY) { |
| | | this.correctY = correctY; |
| | | } |
| | | |
| | | public Boolean getDirect() { |
| | | return direct; |
| | | } |
| | | |
| | | public void setDirect(Boolean direct) { |
| | | this.direct = direct; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | |
| | | import kr.wisestone.owl.domain.enumType.ServiceType; |
| | | import kr.wisestone.owl.util.DateUtil; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.math.BigInteger; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-13. |
| | | */ |
| | | @Entity |
| | | public class Workspace extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | private static final Long DEFAULT_FREE_ALLOCATE_DISK = 10737418240L; |
| | | private static final Long DEFAULT_USER_ALLOCATE_DISK = 3221225472L; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | | private Long id; |
| | | private String name; |
| | | private Integer maxUser; |
| | | private Date startDate; |
| | | private Date expireDate; |
| | | private Long storageSize = 0L; |
| | | private Long useTraffic = 0L; // 트레픽 사용량 측정 |
| | | @Enumerated(EnumType.STRING) |
| | | private ServiceType serviceType; // 사용자가 서비스를 취소할 경우에 UNUSED 로 값이 변경된다. - 일반적인 경우에는 USE 값이다. |
| | | |
| | | @OneToOne(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Payment payment; |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<AttachedFile> attachedFiles = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<Project> projects = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<CustomField> customFields = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueType> issueTypes = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<Workflow> workflows = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueStatus> issueStatuses = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<UserWorkspace> userWorkspaces = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<UserInvite> userInvites = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<PaymentHistory> paymentHistories = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueUser> issueUsers = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueRisk> issueRisks = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueComment> issueComments = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<UserLikeIssue> userLikeIssues = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = { CascadeType.ALL }, orphanRemoval = true) |
| | | private Set<IssueSearch> issueSearches = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<IssueTableConfig> issueTableConfigs = new HashSet<>(); |
| | | |
| | | @OneToMany(mappedBy = "workspace", cascade = {CascadeType.ALL}, orphanRemoval = true) |
| | | private Set<Priority> priorities = new HashSet<>(); |
| | | |
| | | |
| | | |
| | | public Workspace() { |
| | | } |
| | | |
| | | public Long getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public Integer getMaxUser() { |
| | | return maxUser; |
| | | } |
| | | |
| | | public void setMaxUser(Integer maxUser) { |
| | | this.maxUser = maxUser; |
| | | } |
| | | |
| | | public Date getStartDate() { |
| | | return startDate; |
| | | } |
| | | |
| | | public void setStartDate(Date startDate) { |
| | | this.startDate = startDate; |
| | | } |
| | | |
| | | public Date getExpireDate() { |
| | | return expireDate; |
| | | } |
| | | |
| | | public void setExpireDate(Date expireDate) { |
| | | this.expireDate = expireDate; |
| | | } |
| | | |
| | | public Long getStorageSize() { |
| | | return storageSize; |
| | | } |
| | | |
| | | public void setStorageSize(Long storageSize) { |
| | | this.storageSize = storageSize; |
| | | } |
| | | |
| | | public Payment getPayment() { |
| | | return payment; |
| | | } |
| | | |
| | | public void setPayment(Payment payment) { |
| | | this.payment = payment; |
| | | } |
| | | |
| | | public Set<PaymentHistory> getPaymentHistories() { |
| | | return paymentHistories; |
| | | } |
| | | |
| | | public void setPaymentHistories(Set<PaymentHistory> paymentHistories) { |
| | | this.paymentHistories = paymentHistories; |
| | | } |
| | | |
| | | public Long calculateStorageSize() { |
| | | // 10명 이하는 5GB 제공 |
| | | if (this.maxUser < 11) { |
| | | return DEFAULT_FREE_ALLOCATE_DISK; |
| | | } |
| | | |
| | | // 10명 이상은 10GB + 사용자수 * 3기가 제공 |
| | | return DEFAULT_FREE_ALLOCATE_DISK + (this.maxUser * DEFAULT_USER_ALLOCATE_DISK); |
| | | } |
| | | |
| | | public Set<Project> getProjects() { |
| | | return projects; |
| | | } |
| | | |
| | | public void setProjects(Set<Project> projects) { |
| | | this.projects = projects; |
| | | } |
| | | |
| | | public Set<IssueStatus> getIssueStatuses() { |
| | | return issueStatuses; |
| | | } |
| | | |
| | | public void setIssueStatuses(Set<IssueStatus> issueStatuses) { |
| | | this.issueStatuses = issueStatuses; |
| | | } |
| | | |
| | | public Set<AttachedFile> getAttachedFiles() { |
| | | return attachedFiles; |
| | | } |
| | | |
| | | public void setAttachedFiles(Set<AttachedFile> attachedFiles) { |
| | | this.attachedFiles = attachedFiles; |
| | | } |
| | | |
| | | public Set<UserWorkspace> getUserWorkspaces() { |
| | | return userWorkspaces; |
| | | } |
| | | |
| | | public void setUserWorkspaces(Set<UserWorkspace> userWorkspaces) { |
| | | this.userWorkspaces = userWorkspaces; |
| | | } |
| | | |
| | | public Set<UserInvite> getUserInvites() { |
| | | return userInvites; |
| | | } |
| | | |
| | | public void setUserInvites(Set<UserInvite> userInvites) { |
| | | this.userInvites = userInvites; |
| | | } |
| | | |
| | | public Set<IssueType> getIssueTypes() { |
| | | return issueTypes; |
| | | } |
| | | |
| | | public void setIssueTypes(Set<IssueType> issueTypes) { |
| | | this.issueTypes = issueTypes; |
| | | } |
| | | |
| | | public Set<Workflow> getWorkflows() { |
| | | return workflows; |
| | | } |
| | | |
| | | public void setWorkflows(Set<Workflow> workflows) { |
| | | this.workflows = workflows; |
| | | } |
| | | |
| | | public Set<CustomField> getCustomFields() { |
| | | return customFields; |
| | | } |
| | | |
| | | public void setCustomFields(Set<CustomField> customFields) { |
| | | this.customFields = customFields; |
| | | } |
| | | |
| | | public ServiceType getServiceType() { |
| | | return serviceType; |
| | | } |
| | | |
| | | public void setServiceType(ServiceType serviceType) { |
| | | this.serviceType = serviceType; |
| | | } |
| | | |
| | | public Set<IssueUser> getIssueUsers() { |
| | | return issueUsers; |
| | | } |
| | | |
| | | public void setIssueUsers(Set<IssueUser> issueUsers) { |
| | | this.issueUsers = issueUsers; |
| | | } |
| | | |
| | | public Set<IssueRisk> getIssueRisks() { |
| | | return issueRisks; |
| | | } |
| | | |
| | | public void setIssueRisks(Set<IssueRisk> issueRisks) { |
| | | this.issueRisks = issueRisks; |
| | | } |
| | | |
| | | public Set<IssueComment> getIssueComments() { |
| | | return issueComments; |
| | | } |
| | | |
| | | public void setIssueComments(Set<IssueComment> issueComments) { |
| | | this.issueComments = issueComments; |
| | | } |
| | | |
| | | public Set<UserLikeIssue> getUserLikeIssues() { |
| | | return userLikeIssues; |
| | | } |
| | | |
| | | public void setUserLikeIssues(Set<UserLikeIssue> userLikeIssues) { |
| | | this.userLikeIssues = userLikeIssues; |
| | | } |
| | | |
| | | public Long getUseTraffic() { |
| | | return useTraffic; |
| | | } |
| | | |
| | | public void setUseTraffic(Long useTraffic) { |
| | | this.useTraffic = useTraffic; |
| | | } |
| | | |
| | | public Set<IssueSearch> getIssueSearches() { |
| | | return issueSearches; |
| | | } |
| | | |
| | | public void setIssueSearches(Set<IssueSearch> issueSearches) { |
| | | this.issueSearches = issueSearches; |
| | | } |
| | | |
| | | public Set<IssueTableConfig> getIssueTableConfigs() { |
| | | return issueTableConfigs; |
| | | } |
| | | |
| | | public void setIssueTableConfigs(Set<IssueTableConfig> issueTableConfigs) { |
| | | this.issueTableConfigs = issueTableConfigs; |
| | | } |
| | | |
| | | public Set<Priority> getPriorities() { |
| | | return priorities; |
| | | } |
| | | |
| | | public void setPriorities(Set<Priority> priorities) { |
| | | this.priorities = priorities; |
| | | } |
| | | |
| | | public String makeCustomerUid(String account) { |
| | | account = account.replaceAll(".", "_"); |
| | | |
| | | MessageDigest messageDigest = null; |
| | | |
| | | try { |
| | | messageDigest = MessageDigest.getInstance("MD5"); |
| | | } catch (NoSuchAlgorithmException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | if (messageDigest != null) { |
| | | byte[] digest = messageDigest.digest((account + this.getId()).getBytes()); |
| | | BigInteger bigInt = new BigInteger(1, digest); |
| | | return bigInt.toString(16); |
| | | } |
| | | else { |
| | | return account + this.getId(); |
| | | } |
| | | } |
| | | |
| | | // OWL ITS 결제는 매달일 경우 30일, 1년일 경우 365일로 한다. |
| | | public Date calculateNextPaymentDate(String decisionType, Date expireDate) { |
| | | Date toDay = new Date(); |
| | | |
| | | if (Payment.MONTH.equals(decisionType)) { |
| | | int compare = toDay.compareTo(expireDate); |
| | | |
| | | if (compare > 0) { |
| | | // 오늘 날짜가 더 클 때 - 한동안 사용안하다가 결제한 경우 |
| | | return DateUtil.addDays(toDay, 30); |
| | | } |
| | | else { |
| | | // 만료 날짜가 같거나 더 클 때 - 만료일에 결제했거나 무료 사용기간에 결제했을 때 |
| | | return DateUtil.addDays(expireDate, 30); |
| | | } |
| | | } |
| | | else { |
| | | // 매년 결제 |
| | | return DateUtil.addDays(expireDate, 365); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-02 |
| | | */ |
| | | public enum AttachedType { |
| | | SUMMER, // 섬머노트에서 업로드 |
| | | ISSUE_ATTACHED, // 이슈에서 업로드 |
| | | TEMP_SUMMER // 섬머노트에서 업로드 했으나 이슈에 연결되지 않은 경우 |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-05-28. |
| | | */ |
| | | public enum CustomFieldType { |
| | | INPUT, |
| | | MULTI_SELECT, |
| | | SINGLE_SELECT |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-14. |
| | | */ |
| | | public enum EmailType { |
| | | WORKSPACE_JOIN, // 회원 가입 |
| | | USER_SEARCH_PASSWORD, // 사용자 비밀번호 찾기 |
| | | USER_WITH_DRAW, // 회원 탈퇴 |
| | | REGULAR_PAYMENT, // 정기 결제 완료 |
| | | REGULAR_PAYMENT_CANCEL, // 정기 결제 취소 |
| | | REGULAR_PAYMENT_CANCEL_BY_ACCOUNTING_MANAGER, // 정기 결제 취소 회계 담당자에게 알림 |
| | | REGULAR_PAYMENT_MODIFY, // 정기 결제 변경 |
| | | WORKSPACE_INVITE_NEW_USER, // 신규 사용자 초대 |
| | | WORKSPACE_MAX_USER_EXCESS, // 업무 공간 사용자 초과 |
| | | WORKSPACE_MAX_STORAGE_EXCESS, // 업무 공간 저장 공간 부족 |
| | | USER_JOIN_STATISTICS, // 사용자 현황 정보 |
| | | TOTAL_STATISTICS, // 전체 시스템 현황 정보 |
| | | WORKSPACE_EXPIRE, // 업무 공간 사용 기간 만료 |
| | | WORKSPACE_EXPIRE_ALARM, // 업무 공간 사용 기간 만료 예정 알림 |
| | | |
| | | |
| | | |
| | | WORKSPACE_INVITE_SYSTEM_USER, // 기존 사용자 초대 |
| | | PROJECT_DEFAULT_EXCLUDE, // 프로젝트의 일반사용자에서 제외 |
| | | PROJECT_DEFAULT_INCLUDE, // 프로젝트에 일반 사용자로 참여 |
| | | PROJECT_MANAGER_EXCLUDE, // 프로젝트에서 관리자 제외 |
| | | PROJECT_MANAGER_INCLUDE, // 프로젝트에 관리자로 참여 |
| | | PROJECT_MANAGER_EXCLUDE_AND_PROJECT_DEFAULT_INCLUDE, // 프로젝트 관리자 제외 후 일반 사용자로 참여 |
| | | PROJECT_DEFAULT_EXCLUDE_AND_PROJECT_MANAGER_INCLUDE, // 일반 사용자에서 제외 후 프로젝트 관리자로 참여 |
| | | ISSUE_ADD, // 이슈 생성 |
| | | ISSUE_MODIFY, // 이슈 수정 |
| | | ISSUE_REMOVE, // 이슈 삭제 |
| | | ISSUE_SEND, // 이슈 정보 이메일로 전달 |
| | | PROJECT_ADD, // 프로젝트 생성 |
| | | PROJECT_MODIFY, // 프로젝트 수정 |
| | | PROJECT_REMOVE, // 프로젝트 삭제 |
| | | ISSUE_ASSIGNEE_INCLUDE, // 이슈 담당자 지정 |
| | | ISSUE_ASSIGNEE_EXCLUDE, // 이슈 담당자 제외 |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-10-11. |
| | | */ |
| | | public enum FileType { |
| | | IMAGE, // 이미지 |
| | | MEDIA, // 미디어 |
| | | DOC, // 문서 |
| | | ETC // 기타 |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-10-08. |
| | | */ |
| | | public enum IssueHistoryType { |
| | | ADD, |
| | | MODIFY, |
| | | DELETE, |
| | | TOTAL |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-10-10. |
| | | */ |
| | | public enum IssueModifyType { |
| | | SEVERITY, |
| | | PRIORITY, |
| | | ISSUE_STATUS, |
| | | ISSUE_TYPE, |
| | | PERIOD, |
| | | ASSIGNEE, |
| | | CUSTOM_FIELD, |
| | | TITLE, |
| | | DESCRIPTION |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Create By J E O N G - S U N / 2019-05-07 |
| | | */ |
| | | public enum IssueReservationType { |
| | | DAY, |
| | | WEEK, |
| | | MONTH, |
| | | YEAR |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-03-09. |
| | | */ |
| | | public enum IssueStatusType { |
| | | READY, |
| | | OPEN, |
| | | CLOSE |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-23. |
| | | */ |
| | | public enum ProjectType { |
| | | RMS_PROJECT, |
| | | BTS_PROJECT, |
| | | TCM_PROJECT |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-10-05. |
| | | */ |
| | | public enum ServiceType { |
| | | USE, // 서비스 사용중 |
| | | UNUSED, // 서비스 만료 |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.enumType; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-21. |
| | | */ |
| | | public enum SocialType { |
| | | GOOGLE, |
| | | NAVER, |
| | | KAKAO, |
| | | FACEBOOK |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.interceptor; |
| | | |
| | | import kr.wisestone.owl.domain.BaseEntity; |
| | | import kr.wisestone.owl.util.ApplicationContextUtil; |
| | | import kr.wisestone.owl.util.WebAppUtil; |
| | | import org.hibernate.CallbackException; |
| | | import org.hibernate.EmptyInterceptor; |
| | | import org.hibernate.type.Type; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | public class AuditLogInterceptor extends EmptyInterceptor { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Override |
| | | public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, |
| | | Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException { |
| | | this.setModifyInfoToEntity(entity, currentState, propertyNames); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, |
| | | Type[] types) throws CallbackException { |
| | | |
| | | this.setRegisterInfo(entity, state, propertyNames); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | private void setModifyInfoToEntity(Object entity, Object[] state, String[] propertyNames) { |
| | | if (entity instanceof BaseEntity) { |
| | | Long loginId = this.getUserId(); |
| | | if (loginId == null) { |
| | | loginId = Long.valueOf(1); |
| | | } |
| | | |
| | | for (int i = 0; i < propertyNames.length; i++) { |
| | | if ("modifyId".equals(propertyNames[i])) { |
| | | state[i] = loginId; |
| | | } else if ("modifyDate".equals(propertyNames[i])) { |
| | | state[i] = new Date(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void setRegisterInfo(Object entity, Object[] state, String[] propertyNames) { |
| | | if (entity instanceof BaseEntity) { |
| | | Long loginId = this.getUserId(); |
| | | if (loginId == null) { |
| | | loginId = Long.valueOf(1); |
| | | } |
| | | |
| | | Date currentDate = new Date(); |
| | | |
| | | for (int i = 0; i < propertyNames.length; i++) { |
| | | if ("registerId".equals(propertyNames[i])) { |
| | | state[i] = loginId; |
| | | } else if ("modifyId".equals(propertyNames[i])) { |
| | | state[i] = loginId; |
| | | } else if ("registerDate".equals(propertyNames[i])) { |
| | | state[i] = currentDate; |
| | | } else if ("modifyDate".equals(propertyNames[i])) { |
| | | state[i] = currentDate; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private Long getUserId() { |
| | | WebAppUtil webAppUtil = ApplicationContextUtil.getBean("webAppUtil", WebAppUtil.class); |
| | | if (webAppUtil == null) { |
| | | return null; |
| | | } |
| | | |
| | | return webAppUtil.getLoginId(); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.strategy; |
| | | |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.hibernate.boot.model.naming.Identifier; |
| | | import org.hibernate.boot.model.naming.PhysicalNamingStrategy; |
| | | import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; |
| | | |
| | | public class PrefixNamingStrategy implements PhysicalNamingStrategy { |
| | | |
| | | @Override |
| | | public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) { |
| | | return convert(identifier); |
| | | } |
| | | |
| | | @Override |
| | | public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) { |
| | | return convert(identifier); |
| | | } |
| | | |
| | | @Override |
| | | public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) { |
| | | return convert(identifier); |
| | | } |
| | | |
| | | @Override |
| | | public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) { |
| | | return convert(identifier); |
| | | } |
| | | |
| | | @Override |
| | | public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) { |
| | | return convert(identifier); |
| | | } |
| | | |
| | | private Identifier convert(Identifier identifier) { |
| | | if (identifier == null || StringUtils.isBlank(identifier.getText())) { |
| | | return identifier; |
| | | } |
| | | |
| | | String regex = "([a-z])([A-Z])"; |
| | | String replacement = "$1_$2"; |
| | | String newName = identifier.getText().replaceAll(regex, replacement).toLowerCase(); |
| | | return Identifier.toIdentifier(newName); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.domain.support; |
| | | |
| | | import org.apache.ibatis.type.BaseTypeHandler; |
| | | import org.apache.ibatis.type.JdbcType; |
| | | import org.apache.ibatis.type.MappedTypes; |
| | | |
| | | import java.sql.*; |
| | | import java.time.ZoneId; |
| | | import java.time.ZonedDateTime; |
| | | import java.util.Calendar; |
| | | import java.util.GregorianCalendar; |
| | | |
| | | @MappedTypes(ZonedDateTime.class) |
| | | public class ZonedDateTimeTypeHandler extends BaseTypeHandler<ZonedDateTime> { |
| | | |
| | | @Override |
| | | public void setNonNullParameter(PreparedStatement ps, int i, ZonedDateTime parameter, JdbcType jdbcType) throws SQLException { |
| | | ps.setTimestamp( |
| | | i, |
| | | Timestamp.from(parameter.toInstant()), |
| | | GregorianCalendar.from(parameter) |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public ZonedDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException { |
| | | Timestamp ts = rs.getTimestamp(columnName, Calendar.getInstance()); |
| | | if (ts != null) { |
| | | return ZonedDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public ZonedDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException { |
| | | Timestamp ts = rs.getTimestamp(columnIndex, Calendar.getInstance()); |
| | | if (ts != null) { |
| | | return ZonedDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public ZonedDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { |
| | | Timestamp ts = cs.getTimestamp(columnIndex, Calendar.getInstance()); |
| | | if (ts != null) { |
| | | return ZonedDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.exception; |
| | | |
| | | import kr.wisestone.owl.vo.MessageVo; |
| | | |
| | | |
| | | public class OwlRuntimeException extends RuntimeException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | private String code; |
| | | |
| | | public OwlRuntimeException() { |
| | | super(); |
| | | } |
| | | |
| | | public OwlRuntimeException(String code, final String message, |
| | | final Throwable cause) { |
| | | super(message, cause); |
| | | this.code = code; |
| | | } |
| | | |
| | | public OwlRuntimeException(String code, final String message) { |
| | | super(message); |
| | | this.code = code; |
| | | } |
| | | |
| | | public OwlRuntimeException(MessageVo message) { |
| | | super(message.getMessage()); |
| | | this.code = message.getCode(); |
| | | } |
| | | |
| | | public OwlRuntimeException(MessageVo message, Throwable t) { |
| | | super(message.getMessage(), t); |
| | | this.code = message.getCode(); |
| | | } |
| | | |
| | | public OwlRuntimeException(Exception e) { |
| | | super(e); |
| | | } |
| | | |
| | | public OwlRuntimeException(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public OwlRuntimeException(String code, Exception e) { |
| | | super(e); |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return this.code; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.initializer; |
| | | |
| | | import org.springframework.security.web.session.HttpSessionEventPublisher; |
| | | import org.springframework.web.WebApplicationInitializer; |
| | | import org.springframework.web.context.ContextLoaderListener; |
| | | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; |
| | | import org.springframework.web.filter.CharacterEncodingFilter; |
| | | import org.springframework.web.filter.DelegatingFilterProxy; |
| | | import org.springframework.web.servlet.DispatcherServlet; |
| | | import javax.servlet.*; |
| | | import java.util.EnumSet; |
| | | |
| | | /** |
| | | * Created by jeong on 2017-08-01. |
| | | */ |
| | | public class AppInitializer implements WebApplicationInitializer { |
| | | |
| | | private static final String CONFIG_LOCATION = "kr.wisestone.owl.config"; |
| | | private static final String MAPPING_URL = "/*"; |
| | | |
| | | @Override |
| | | public void onStartup(ServletContext servletContext) { |
| | | this.registerDispatcherServlet(servletContext); |
| | | this.registerCharacterEncodingFilter(servletContext); |
| | | this.registerSpringSecurityFilter(servletContext); |
| | | } |
| | | |
| | | private void registerDispatcherServlet(ServletContext servletContext) { |
| | | AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); |
| | | context.setConfigLocation(CONFIG_LOCATION); |
| | | servletContext.addListener(new ContextLoaderListener(context)); |
| | | servletContext.addListener(new HttpSessionEventPublisher()); |
| | | |
| | | ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context)); |
| | | dispatcher.setLoadOnStartup(1); |
| | | dispatcher.addMapping(MAPPING_URL); |
| | | |
| | | context.registerShutdownHook(); |
| | | } |
| | | |
| | | private void registerCharacterEncodingFilter(ServletContext servletContext) { |
| | | FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("characterEncodingFilter", new CharacterEncodingFilter()); |
| | | characterEncodingFilter.setInitParameter("encoding", "UTF-8"); |
| | | characterEncodingFilter.setInitParameter("forceEncoding", "true"); |
| | | characterEncodingFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); |
| | | } |
| | | |
| | | private void registerSpringSecurityFilter(ServletContext servletContext) { |
| | | FilterRegistration.Dynamic springSecurityFilter = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy()); |
| | | springSecurityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.AttachedFileCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-27. |
| | | */ |
| | | @Repository |
| | | public interface AttachedFileMapper { |
| | | Long findUseStorage(AttachedFileCondition attachedFileCondition); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceId(Long workspaceId); |
| | | |
| | | List<Map<String, Object>> findByIssueIds(AttachedFileCondition attachedFileCondition); |
| | | |
| | | void deleteAttachedFileByWorkspaceId(Long workspaceId); |
| | | |
| | | void deleteAttachedFileByIssueIds(AttachedFileCondition attachedFileCondition); |
| | | |
| | | void deleteAttachedFileNotId(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.CustomFieldCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-05-28. |
| | | */ |
| | | @Repository |
| | | public interface CustomFieldMapper { |
| | | List<Map<String, Object>> find(CustomFieldCondition customFieldCondition); |
| | | |
| | | Long count(CustomFieldCondition customFieldCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.EventCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Repository |
| | | public interface EventMapper { |
| | | List<Map<String, Object>> find(EventCondition eventCondition); |
| | | |
| | | Long count(EventCondition eventCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.FaqCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Repository |
| | | public interface FaqMapper { |
| | | List<Map<String, Object>> find(FaqCondition faqCondition); |
| | | |
| | | Long count(FaqCondition faqCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.GuideCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Repository |
| | | public interface GuideMapper { |
| | | List<Map<String, Object>> find(GuideCondition guideCondition); |
| | | |
| | | Long count(GuideCondition guideCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-06-07. |
| | | */ |
| | | @Repository |
| | | public interface IssueCustomFieldValueMapper { |
| | | Map<String, Object> findLikeUseValue(IssueCustomFieldValueCondition issueCustomFieldValueCondition); |
| | | |
| | | Map<String, Object> findByUseValue(IssueCustomFieldValueCondition issueCustomFieldValueCondition); |
| | | |
| | | void deleteIssueCustomFieldValue(Long issueTypeCustomFieldId); |
| | | |
| | | List<Map<String, Object>> findInIssueIds(IssueCondition issueCondition); |
| | | |
| | | void deleteByIssueCustomFieldValueId(List<Long> ids); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.IssueHistoryCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-10-17. |
| | | */ |
| | | @Repository |
| | | public interface IssueHistoryMapper { |
| | | List<Map<String, Object>> find(IssueHistoryCondition issueHistoryCondition); |
| | | |
| | | Long count(IssueHistoryCondition issueHistoryCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.repository.query.Param; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-17. |
| | | */ |
| | | @Repository |
| | | public interface IssueMapper { |
| | | List<Map<String, Object>> find(IssueCondition issueCondition); |
| | | |
| | | Long count(IssueCondition issueCondition); |
| | | |
| | | void insertBatch(@Param("issueForms") List<IssueForm> issueForms); |
| | | |
| | | void updateBatch(@Param("issueForms") List<IssueForm> issueForms); |
| | | |
| | | void insertHistoryBatch(List<Map<String, Object>> issueHistoryMaps); |
| | | |
| | | void insertIssueRiskBatch(List<Map<String, Long>> issueRiskMaps); |
| | | |
| | | void insertIssueCustomFieldValueBatch(List<Map<String, Object>> issueCustomFieldValueMaps); |
| | | |
| | | List<Map<String, Object>> findIssueUser(IssueCondition issueCondition); |
| | | |
| | | Long countByIssueTypeId(Long issueTypeId); |
| | | |
| | | Long countByIssueStatusId(Long issueStatusId); |
| | | |
| | | List<Map<String, Object>> findByIssueTypeId(Long issueTypeId); |
| | | |
| | | List<Map<String, Object>> findByProjectId(Long projectId); |
| | | |
| | | List<Map<String, Object>> getAllTaskUser(IssueCondition taskCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.IssueStatusCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-05-09. |
| | | */ |
| | | @Repository |
| | | public interface IssueStatusMapper { |
| | | List<Map<String, Object>> find(IssueStatusCondition issueStatusCondition); |
| | | |
| | | Long count(IssueStatusCondition issueStatusCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.IssueTypeCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-05-29. |
| | | */ |
| | | @Repository |
| | | public interface IssueTypeMapper { |
| | | List<Map<String, Object>> find(IssueTypeCondition issueTypeCondition); |
| | | |
| | | Long count(IssueTypeCondition issueTypeCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-11-27. |
| | | */ |
| | | @Repository |
| | | public interface IssueUserMapper { |
| | | void insertIssueUser(List<Map<String, Long>> issueRoleUserMaps); |
| | | |
| | | void deleteIssueUserByIssueIdAndMultiUserId(Map<String, Object> removeIssueAssigneeMap); |
| | | |
| | | void deleteIssueUserByUserIdAndMultiIssueId(Map<String, Object> removeIssueAssigneeMap); |
| | | |
| | | List<Map<String, Object>> findByUserIdAndProjectId(Map<String, Object> issueUserMap); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.NoticeCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Repository |
| | | public interface NoticeMapper { |
| | | List<Map<String, Object>> find(NoticeCondition noticeCondition); |
| | | |
| | | Long count(NoticeCondition noticeCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-23. |
| | | */ |
| | | @Repository |
| | | public interface ProjectMapper { |
| | | |
| | | List<Map<String, Object>> find(ProjectCondition projectCondition); |
| | | |
| | | Long count(ProjectCondition projectCondition); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceManager(ProjectCondition projectCondition); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceManagerAll(ProjectCondition projectCondition); |
| | | |
| | | Long countByWorkspaceManager(ProjectCondition projectCondition); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceIdAndIncludeProject(ProjectCondition projectCondition); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceIdAndIncludeProjectAll(ProjectCondition projectCondition); |
| | | |
| | | void deleteProject(Map<String, Object> deleteProjectMap); |
| | | |
| | | List<Map<String, Object>> checkIncludeProject(ProjectCondition projectCondition); |
| | | |
| | | List<Map<String, Object>> findChildrenProject(Long parentProjectId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-11-27. |
| | | */ |
| | | @Repository |
| | | public interface ProjectRoleUserMapper { |
| | | void insertProjectRoleUser(List<Map<String, Long>> projectRoleUserMaps); |
| | | |
| | | void deleteProjectRoleUser(Map<String, Long> projectRoleUserMap); |
| | | |
| | | List<Map<String, Object>> findProjectRoleUser(Map<String, Object> projectRoleUserMap); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.QnaCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Repository |
| | | public interface QnaMapper { |
| | | List<Map<String, Object>> find(QnaCondition qnaCondition); |
| | | |
| | | Long count(QnaCondition qnaCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.UserCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-26. |
| | | */ |
| | | @Repository |
| | | public interface UserMapper { |
| | | List<Map<String, Object>> find(UserCondition userCondition); |
| | | |
| | | List<Map<String, Object>> findAdmin(); |
| | | |
| | | List<Map<String, Object>> findProjectMember(UserCondition userCondition); |
| | | |
| | | Long count(UserCondition userCondition); |
| | | |
| | | void deleteCascadeUser(UserCondition userCondition); |
| | | |
| | | List<Map<String, Object>> findByReservationNotifyTime(Map<String, Object> conditions); |
| | | |
| | | List<Map<String, Object>> findByAllWorkspace(UserCondition userCondition); |
| | | |
| | | Long countByAllWorkspace(UserCondition userCondition); |
| | | |
| | | List<Map<String, Object>> findEvent(); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.UserWorkspaceCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-10-02. |
| | | */ |
| | | @Repository |
| | | public interface UserWorkspaceMapper { |
| | | List<Map<String, Object>> find(UserWorkspaceCondition userWorkspaceCondition); |
| | | |
| | | Long count(UserWorkspaceCondition userWorkspaceCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.WidgetCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-11. |
| | | */ |
| | | @Repository |
| | | public interface WidgetMapper { |
| | | |
| | | // 완료된 이슈 |
| | | Long countCompleteIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 미할당 이슈 |
| | | Long countNoAssigneeIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 내가 등록한 이슈 |
| | | List<Map<String, Object>> findRegisterIssue(WidgetCondition widgetCondition); |
| | | // 내가 오늘 등록한 이슈 갯수 |
| | | Long countTodayRegisterIssue(WidgetCondition widgetCondition); |
| | | Long countRegisterIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 할당된 이슈 |
| | | Long countAssigneeIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 지연된 이슈 |
| | | List<Map<String, Object>> findDelayIssue(WidgetCondition widgetCondition); |
| | | Long countDelayIssue(WidgetCondition widgetCondition); |
| | | Long countTodayDelayIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 잔여 이슈 |
| | | Long countRemainIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 진행중인 프로젝트 현황(참여중인 프로젝트) |
| | | List<Map<String, Object>> findProjectProgress(WidgetCondition widgetCondition); |
| | | |
| | | // 진행중인 프로젝트 현황(전체) |
| | | List<Map<String, Object>> findProjectProgressAll(WidgetCondition widgetCondition); |
| | | |
| | | // 나에게 할당된 이슈 |
| | | List<Map<String, Object>> findMyAssigneeIssue(WidgetCondition widgetCondition); |
| | | // 내가 오늘 할당받은 이슈 갯수 |
| | | Long countTodayMyAssigneeIssue(WidgetCondition widgetCondition); |
| | | Long countMyAssigneeIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 멤버별 진행률 |
| | | List<Map<String, Object>> findProjectMemberIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 등록한 이슈 중 완료 갯수 |
| | | List<Map<String, Object>> findMyRegisterCompleteIssue(WidgetCondition widgetCondition); |
| | | // 등록한 이슈 중 진행 갯수 |
| | | List<Map<String, Object>> findMyRegisterRemainIssue(WidgetCondition widgetCondition); |
| | | // 담당한 이슈 중 완료 갯수 |
| | | List<Map<String, Object>> findMyAssigneeCompleteIssue(WidgetCondition widgetCondition); |
| | | // 담당한 이슈 중 진행 갯수 |
| | | List<Map<String, Object>> findMyAssigneeRemainIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 위험 관리 |
| | | List<Map<String, Object>> findRiskIssue(WidgetCondition widgetCondition); |
| | | Map<String, Object> countChangeStatusAndAssigneeIssue(WidgetCondition widgetCondition); |
| | | Long countRiskIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 전체 이슈 처리 현황 |
| | | List<Map<String, Object>> findIssueComplete(WidgetCondition widgetCondition); |
| | | Long countTotalIssue(WidgetCondition widgetCondition); |
| | | |
| | | // 상태별 이슈 현황 |
| | | List<Map<String, Object>> findByStandIssueStatus(WidgetCondition widgetCondition); |
| | | |
| | | List<Map<String, Object>> findByStandIssueType(WidgetCondition widgetCondition); |
| | | |
| | | //중요도 별 이슈 갯수 |
| | | List<Map<String, Object>> countSeverityIssue(WidgetCondition widgetCondition); |
| | | //중요도 이슈 목록 |
| | | List<Map<String, Object>> findSeverityIssues(WidgetCondition widgetCondition); |
| | | //중요도 드롭다운 별 항목 갯수 |
| | | Long countSearchIssue(WidgetCondition widgetCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.WorkflowCondition; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-05-10. |
| | | */ |
| | | @Repository |
| | | public interface WorkflowMapper { |
| | | List<Map<String, Object>> find(WorkflowCondition workflowCondition); |
| | | |
| | | Long count(WorkflowCondition workflowCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-11-29. |
| | | */ |
| | | @Repository |
| | | public interface WorkspaceMapper { |
| | | void deleteWorkspace(Map<String, Object> deleteWorkspaceMap); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.monitor; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-09. |
| | | */ |
| | | public class Email { |
| | | public Date received; |
| | | public String from; |
| | | public List<String> to = Lists.newArrayList(); |
| | | public List<String> cc = Lists.newArrayList(); |
| | | public String subject; |
| | | public String body; |
| | | public List<EmailAttachment> attachments = Lists.newArrayList(); |
| | | |
| | | public Email(){} |
| | | |
| | | public Date getReceived() { |
| | | return received; |
| | | } |
| | | |
| | | public void setReceived(Date received) { |
| | | this.received = received; |
| | | } |
| | | |
| | | public String getFrom() { |
| | | return from; |
| | | } |
| | | |
| | | public void setFrom(String from) { |
| | | this.from = from; |
| | | } |
| | | |
| | | public List<String> getTo() { |
| | | return to; |
| | | } |
| | | |
| | | public void setTo(List<String> to) { |
| | | this.to = to; |
| | | } |
| | | |
| | | public List<String> getCc() { |
| | | return cc; |
| | | } |
| | | |
| | | public void setCc(List<String> cc) { |
| | | this.cc = cc; |
| | | } |
| | | |
| | | public String getSubject() { |
| | | return subject; |
| | | } |
| | | |
| | | public void setSubject(String subject) { |
| | | this.subject = subject; |
| | | } |
| | | |
| | | public String getBody() { |
| | | return body; |
| | | } |
| | | |
| | | public void setBody(String body) { |
| | | this.body = body; |
| | | } |
| | | |
| | | public List<EmailAttachment> getAttachments() { |
| | | return attachments; |
| | | } |
| | | |
| | | public void setAttachments(List<EmailAttachment> attachments) { |
| | | this.attachments = attachments; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.monitor; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-02-09. |
| | | */ |
| | | public class EmailAttachment { |
| | | public String name; |
| | | public String path; |
| | | public Long size; |
| | | |
| | | public EmailAttachment(){} |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | public void setName(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getPath() { |
| | | return path; |
| | | } |
| | | |
| | | public void setPath(String path) { |
| | | this.path = path; |
| | | } |
| | | |
| | | public Long getSize() { |
| | | return size; |
| | | } |
| | | |
| | | public void setSize(Long size) { |
| | | this.size = size; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.monitor; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.util.WebAppUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | |
| | | import javax.mail.*; |
| | | import javax.mail.internet.MimeBodyPart; |
| | | import javax.mail.internet.MimeUtility; |
| | | import javax.mail.search.FlagTerm; |
| | | import java.io.*; |
| | | import java.util.List; |
| | | import java.util.Properties; |
| | | |
| | | /** |
| | | * Created by jeong on 2018-02-08. |
| | | */ |
| | | public class MailMonitor { |
| | | private static final Logger log = LoggerFactory.getLogger(MailMonitor.class); |
| | | |
| | | private volatile static MailMonitor uniqueInstance; |
| | | private Store store; |
| | | private String downloadDirectory = ""; |
| | | private String userName = ""; |
| | | private String password = ""; |
| | | |
| | | private MailMonitor() { |
| | | // 시스템 프로퍼티를 읽어 다운로드 경로를 지정 |
| | | this.initMailProperties(); |
| | | this.connectEmail(); |
| | | } |
| | | |
| | | public static MailMonitor getInstance() { |
| | | if (uniqueInstance == null) { |
| | | synchronized (MailMonitor.class) { |
| | | if (uniqueInstance == null) { |
| | | uniqueInstance = new MailMonitor(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return uniqueInstance; |
| | | } |
| | | |
| | | private void initMailProperties() { |
| | | Properties properties = new Properties(); |
| | | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); |
| | | InputStream inputStream = classLoader.getResourceAsStream("system.properties"); |
| | | |
| | | try { |
| | | properties.load(inputStream); |
| | | this.downloadDirectory = properties.getProperty("mail.file.path"); |
| | | this.userName = properties.getProperty("mail.account"); |
| | | this.password = properties.getProperty("mail.password"); |
| | | } catch (IOException e) { |
| | | log.debug("initMailProperties() : " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | private void connectEmail() { |
| | | Properties properties = new Properties(); |
| | | properties.setProperty("mail.host", "imap.gmail.com"); |
| | | properties.setProperty("mail.port", "995"); |
| | | properties.setProperty("mail.transport.protocol", "imaps"); |
| | | |
| | | Session session = Session.getInstance(properties, |
| | | new javax.mail.Authenticator() { |
| | | protected PasswordAuthentication getPasswordAuthentication() { |
| | | return new PasswordAuthentication(userName, password); |
| | | } |
| | | }); |
| | | |
| | | try { |
| | | this.store = session.getStore("imaps"); |
| | | this.store.connect(); |
| | | } catch (MessagingException e) { |
| | | log.debug("connectEmail() : " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // TODO - 이메일 연동 시스템에서 추가적으로 사용자가 이메일을 보내고 싶은 프로젝트를 선택하는 설정 화면 개발이 필요하다. |
| | | public List<Email> readMails() { |
| | | Folder inbox = null; |
| | | List<Email> emails = Lists.newArrayList(); |
| | | |
| | | try { |
| | | inbox = store.getFolder("INBOX"); |
| | | inbox.open(Folder.READ_WRITE); |
| | | |
| | | Message messages[] = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false)); |
| | | |
| | | System.out.println("Number of mails = " + messages.length); |
| | | |
| | | for (Message message : messages) { |
| | | Email email = new Email(); |
| | | Address[] from = message.getFrom(); |
| | | |
| | | /*System.out.println("-------------------------------"); |
| | | System.out.println("Date : " + message.getSentDate()); |
| | | System.out.println("From : " + MimeUtility.decodeText(from[0].toString())); |
| | | System.out.println("Subject: " + MimeUtility.decodeText(message.getSubject())); |
| | | System.out.println("Content :");*/ |
| | | |
| | | String contentType = message.getContentType(); |
| | | String messageContent = ""; |
| | | List<EmailAttachment> emailAttachments = Lists.newArrayList(); |
| | | |
| | | if (contentType.contains("multipart")) { |
| | | Multipart multiPart = (Multipart) message.getContent(); |
| | | int numberOfParts = multiPart.getCount(); |
| | | |
| | | for (int partCount = 0; partCount < numberOfParts; partCount++) { |
| | | MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount); |
| | | if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) { |
| | | // 첨부 파일 |
| | | String fileName = MimeUtility.decodeText(part.getFileName()); |
| | | EmailAttachment emailAttachment = new EmailAttachment(); |
| | | emailAttachment.setName(fileName); |
| | | emailAttachment.setPath(this.downloadDirectory + fileName); |
| | | emailAttachments.add(emailAttachment); |
| | | |
| | | part.saveFile(this.downloadDirectory + fileName); |
| | | } |
| | | else { |
| | | // 본문 텍스트 |
| | | messageContent = this.getText(part); |
| | | } |
| | | } |
| | | } |
| | | else if (contentType.contains("text/plain") || contentType.contains("text/html")) { |
| | | Object content = message.getContent(); |
| | | if (content != null) { |
| | | // 본문 텍스트 |
| | | messageContent = content.toString(); |
| | | } |
| | | } |
| | | |
| | | /*System.out.println("\t Message: " + messageContent); |
| | | System.out.println("--------------------------------");*/ |
| | | |
| | | email.setSubject(message.getSubject()); |
| | | email.setFrom(MimeUtility.decodeText(from[0].toString())); |
| | | email.setBody(messageContent); |
| | | email.setAttachments(emailAttachments); |
| | | emails.add(email); |
| | | } |
| | | |
| | | //inbox.setFlags(messages, new Flags(Flags.Flag.SEEN), true); |
| | | |
| | | /*inbox.close(true); |
| | | this.store.close();*/ |
| | | } catch (NoSuchProviderException e) { |
| | | log.debug("readMails() : "+ e.getMessage()); |
| | | e.printStackTrace(); |
| | | } catch (MessagingException e) { |
| | | log.debug("readMails() : "+ e.getMessage()); |
| | | e.printStackTrace(); |
| | | } catch (UnsupportedEncodingException e) { |
| | | log.debug("readMails() : "+ e.getMessage()); |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | log.debug("readMails() : "+ e.getMessage()); |
| | | e.printStackTrace(); |
| | | } |
| | | finally{ |
| | | this.closeFolder(inbox); |
| | | } |
| | | |
| | | return emails; |
| | | } |
| | | |
| | | private String getText(Part part) throws MessagingException, IOException { |
| | | if (part.isMimeType("text/*")) { |
| | | return (String) part.getContent(); |
| | | } |
| | | |
| | | if (part.isMimeType("multipart/alternative")) { |
| | | // prefer html text over plain text |
| | | Multipart mp = (Multipart) part.getContent(); |
| | | String text = null; |
| | | for (int i = 0; i < mp.getCount(); i++) { |
| | | Part bp = mp.getBodyPart(i); |
| | | if (bp.isMimeType("text/plain")) { |
| | | if (text == null) { |
| | | text = this.getText(bp); |
| | | } |
| | | continue; |
| | | } |
| | | else if (bp.isMimeType("text/html")) { |
| | | String content = this.getText(bp); |
| | | if (content != null) { |
| | | return content; |
| | | } |
| | | } |
| | | else { |
| | | return this.getText(bp); |
| | | } |
| | | } |
| | | return text; |
| | | } |
| | | else if (part.isMimeType("multipart/*")) { |
| | | Multipart mp = (Multipart) part.getContent(); |
| | | for (int i = 0; i < mp.getCount(); i++) { |
| | | String content = this.getText(mp.getBodyPart(i)); |
| | | if (content != null) { |
| | | return content; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | private void closeFolder(Folder inbox) { |
| | | try { |
| | | if (inbox != null) { |
| | | inbox.close(false); |
| | | } |
| | | |
| | | } catch (MessagingException e) { |
| | | log.debug("closeFolder() : "+ e.getMessage()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.AttachedFile; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface AttachedFileRepository extends JpaRepository<AttachedFile, Long> { |
| | | List<AttachedFile> findByIssueId(@Param("issueId") Long issueId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.CustomField; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface CustomFieldRepository extends JpaRepository<CustomField, Long> { |
| | | |
| | | CustomField findByNameAndWorkspaceId(@Param("name") String name, @Param("workspaceId") Long workspaceId); |
| | | |
| | | CustomField findByNameAndWorkspaceIdAndIdNot(@Param("name") String name, @Param("workspaceId") Long workspaceId, @Param("id") Long id); |
| | | |
| | | List<CustomField> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.CustomFieldValue; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface CustomFieldValueRepository extends JpaRepository<CustomFieldValue, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Event; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Modifying; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | public interface EventRepository extends JpaRepository<Event, Long> { |
| | | @Modifying |
| | | @Transactional |
| | | @Query(name = "Event.updateInActivation") |
| | | void updateInActivation(@Param("eventId") Long eventId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Faq; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface FaqRepository extends JpaRepository<Faq, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Guide; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Modifying; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | public interface GuideRepository extends JpaRepository<Guide, Long> { |
| | | @Modifying |
| | | @Transactional |
| | | @Query(name = "Guide.updateInActivation") |
| | | void updateInActivation(@Param("guideId") Long guideId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueComment; |
| | | import kr.wisestone.owl.vo.IssueCommentVo; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface IssueCommentRepository extends JpaRepository<IssueComment, Long> { |
| | | |
| | | @Query(name="IssueComment.findByIssueId") |
| | | List<IssueCommentVo> findByIssueId(@Param("issueId") Long issueId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueCustomFieldValue; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface IssueCustomFieldValueRepository extends JpaRepository<IssueCustomFieldValue, Long> { |
| | | |
| | | List<IssueCustomFieldValue> findByIssueId(@Param("issueId") Long issueId); |
| | | |
| | | List<IssueCustomFieldValue> findByCustomFieldId(@Param("customFieldId") Long customFieldId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueHistory; |
| | | import kr.wisestone.owl.vo.IssueHistoryVo; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface IssueHistoryRepository extends JpaRepository<IssueHistory, Long> { |
| | | @Query(name="IssueHistory.findByIssueId") |
| | | List<IssueHistoryVo> findByIssueId(@Param("issueId") Long issueId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueNumberGenerator; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | public interface IssueNumberGeneratorRepository extends JpaRepository<IssueNumberGenerator, Long> { |
| | | IssueNumberGenerator findByProjectId(@Param("projectId") Long projectId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueRelation; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface IssueRelationRepository extends JpaRepository<IssueRelation, Long> { |
| | | List<IssueRelation> findAllByIssueId(Long issueId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface IssueRepository extends JpaRepository<Issue, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueReservation; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface IssueReservationRepository extends JpaRepository<IssueReservation, Long> { |
| | | List<IssueReservation> findByIssueReservationTypeNotNull(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueRisk; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface IssueRiskRepository extends JpaRepository<IssueRisk, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueSearch; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface IssueSearchRepository extends JpaRepository<IssueSearch, Long> { |
| | | IssueSearch findByUserIdAndWorkspaceId(Long userId, Long workspaceId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueStatus; |
| | | import kr.wisestone.owl.domain.enumType.IssueStatusType; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface IssueStatusRepository extends JpaRepository<IssueStatus, Long> { |
| | | List<IssueStatus> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | |
| | | IssueStatus findByNameAndWorkspaceId(@Param("name") String name, @Param("workspaceId") Long workspaceId); |
| | | |
| | | IssueStatus findByNameAndWorkspaceIdAndIdNot(@Param("name") String name, @Param("workspaceId") Long workspaceId, @Param("id") Long id); |
| | | |
| | | IssueStatus findByWorkspaceIdAndIssueStatusType(@Param("workspaceId") Long workspaceId, @Param("issueStatusType") IssueStatusType issueStatusType); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueTableConfig; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | public interface IssueTableConfigRepository extends JpaRepository<IssueTableConfig, Long> { |
| | | IssueTableConfig findByUserIdAndWorkspaceId(@Param("userId") Long userId, @Param("workspaceId") Long workspaceId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueTypeCustomField; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface IssueTypeCustomFieldRepository extends JpaRepository<IssueTypeCustomField, Long> { |
| | | List<IssueTypeCustomField> findByProjectIdAndIssueTypeId(@Param("projectId") Long projectId, @Param("issueTypeId") Long issueTypeId); |
| | | |
| | | List<IssueTypeCustomField> findByProjectIdAndIssueTypeIdOrderByPosition(@Param("projectId") Long projectId, @Param("issueTypeId") Long issueTypeId); |
| | | |
| | | IssueTypeCustomField findByProjectIdAndIssueTypeIdAndCustomFieldId(@Param("projectId") Long projectId, @Param("issueTypeId") Long issueTypeId, @Param("customFieldId") Long customFieldId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueType; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface IssueTypeRepository extends JpaRepository<IssueType, Long> { |
| | | |
| | | IssueType findByNameAndWorkspaceId(@Param("name") String name, @Param("workspaceId") Long workspaceId); |
| | | |
| | | IssueType findByNameAndWorkspaceIdAndIdNot(@Param("name") String name, @Param("workspaceId") Long workspaceId, @Param("id") Long id); |
| | | |
| | | IssueType findByName(@Param("name") String name); |
| | | |
| | | List<IssueType> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueUser; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import java.util.List; |
| | | |
| | | public interface IssueUserRepository extends JpaRepository<IssueUser, Long> { |
| | | List<IssueUser> findByIssueId(Long issueId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.IssueVersion; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface IssueVersionRepository extends JpaRepository<IssueVersion, Long> { |
| | | List<IssueVersion> findByIssueId(@Param("issueId") Long issueId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Notice; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface NoticeRepository extends JpaRepository<Notice, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.PaymentHistory; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface PaymentHistoryRepository extends JpaRepository<PaymentHistory, Long> { |
| | | |
| | | List<PaymentHistory> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Payment; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface PaymentRepository extends JpaRepository<Payment, Long> { |
| | | } |
New file |
| | |
| | | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Permission; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface PermissionRepository extends JpaRepository<Permission, Long> { |
| | | @Query(name="Permission.findByUserId") |
| | | List<Permission> findByUserId(@Param("userId") Long userId); |
| | | |
| | | List<Permission> findByRoleType(@Param("roleType") String roleType); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Priority; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface PriorityRepository extends JpaRepository<Priority, Long> { |
| | | List<Priority> findByWorkspaceIdOrderByPosition(@Param("workspaceId") Long workspaceId); |
| | | |
| | | List<Priority> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Priority; |
| | | import kr.wisestone.owl.domain.ProjectClosure; |
| | | import kr.wisestone.owl.domain.ProjectRole; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface ProjectClosureRepository extends JpaRepository<ProjectClosure, Long> { |
| | | ProjectClosure findByProjectId(@Param("project_Id") Long projectId); |
| | | List<ProjectClosure> findByParentProjectId(@Param("parent_Project_Id") Long parentProjectId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import com.amazonaws.services.route53.model.transform.ListGeoLocationsResultStaxUnmarshaller; |
| | | import kr.wisestone.owl.domain.Project; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface ProjectRepository extends JpaRepository<Project, Long> { |
| | | Project findByProjectKeyAndWorkspaceId(@Param("projectKey") String projectKey, @Param("workspaceId") Long workspaceId); |
| | | |
| | | Project findByNameAndWorkspaceId(@Param("name") String name, @Param("workspaceId") Long workspaceId); |
| | | |
| | | Project findByNameAndWorkspaceIdAndIdNot(@Param("name") String name, @Param("workspaceId") Long workspaceId, @Param("id") Long id); |
| | | |
| | | List<Project> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | |
| | | Project findByWorkspaceIdAndDefaultYn(@Param("workspaceId") Long workspaceId, @Param("defaultYn") Boolean defaultYn); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.ProjectRolePermission; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface ProjectRolePermissionRepository extends JpaRepository<ProjectRolePermission, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.ProjectRole; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | public interface ProjectRoleRepository extends JpaRepository<ProjectRole, Long> { |
| | | ProjectRole findByProjectId(@Param("projectId") Long projectId); |
| | | |
| | | ProjectRole findByProjectIdAndRoleType(@Param("projectId") Long projectId, @Param("roleType") String roleType); |
| | | |
| | | @Query(name="ProjectRole.findByUserIdAndProjectId") |
| | | ProjectRole findByUserIdAndProjectId(@Param("userId") Long userId, @Param("projectId") Long projectId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.ProjectRoleUser; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface ProjectRoleUserRepository extends JpaRepository<ProjectRoleUser, Long> { |
| | | List<ProjectRoleUser> findByProjectRoleId(@Param("projectRoleId") Long projectRoleId); |
| | | |
| | | ProjectRoleUser findByProjectRoleIdAndUserId(@Param("projectRoleId") Long projectRoleId, @Param("userId") Long userId); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Qna; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface QnaRepository extends JpaRepository<Qna, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.ReservationDisableUser; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface ReservationDisableUserRepository extends JpaRepository<ReservationDisableUser, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Severity; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface SeverityRepository extends JpaRepository<Severity, Long> { |
| | | List<Severity> findByWorkspaceIdOrderByPosition(@Param("workspaceId") Long workspaceId); |
| | | |
| | | List<Severity> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.SystemEmail; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface SystemEmailRepository extends JpaRepository<SystemEmail, Long> { |
| | | List<SystemEmail> findBySendAddressAndSendYn(@Param("sendAddress") String sendAddress, @Param("sendYn") Boolean sendYn); |
| | | } |
New file |
| | |
| | | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.SystemRolePermission; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface SystemRolePermissionRepository extends JpaRepository<SystemRolePermission, Long> { |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.SystemRole; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | public interface SystemRoleRepository extends JpaRepository<SystemRole, Long> { |
| | | SystemRole findByRoleType(@Param("roleType") String roleType); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.SystemRoleUser; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface SystemRoleUserRepository extends JpaRepository<SystemRoleUser, Long> { |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.SystemRoleUser; |
| | | import kr.wisestone.owl.domain.UserHistory; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface UserHistoryRepository extends JpaRepository<UserHistory, Long> { |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.UserInviteProject; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface UserInviteProjectRepository extends JpaRepository<UserInviteProject, Long> { |
| | | List<UserInviteProject> findByUserInviteIdAndProjectId(@Param("userInviteId") Long userInviteId, @Param("projectId") Long projectId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.UserInvite; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface UserInviteRepository extends JpaRepository<UserInvite, Long> { |
| | | |
| | | List<UserInvite> findByEmailAndStatus(@Param("email") String email, @Param("status") String status); |
| | | |
| | | UserInvite findByEmailAndWorkspaceId(@Param("email") String email, @Param("workspaceId") Long workspaceId); |
| | | |
| | | List<UserInvite> findByWorkspaceIdAndEmailIn(@Param("workspaceId") Long workspaceId, @Param("emails") List<String> emails); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.vo.UserVo; |
| | | import org.springframework.data.domain.Page; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface UserRepository extends JpaRepository<User, Long> { |
| | | |
| | | User findByAccount(String account); |
| | | |
| | | User findByIdNotAndAccount(@Param("id") Long id, @Param("account") String account); |
| | | |
| | | List<User> findByStatus(@Param("status") String status); |
| | | |
| | | @Query(name = "User.findByWorkspaceIdAndManagerYn") |
| | | User findByWorkspaceIdAndManagerYn(@Param("workspaceId") Long workspaceId, @Param("managerYn") Boolean managerYn); |
| | | |
| | | List<User> findByIdIn(@Param("userIds") List<Long> userIds); |
| | | |
| | | @Query(name = "User.findJoinDay") |
| | | List<User> findJoinDay(@Param("todayFrom") Date todayFrom, @Param("todayTo") Date todayTo); |
| | | |
| | | @Query(name = "User.findAdmin") |
| | | List<User> findAdmin(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.UserWithDraw; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | public interface UserWithDrawRepository extends JpaRepository<UserWithDraw, Long> { |
| | | |
| | | UserWithDraw findByAccount(@Param("account") String account); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.UserWorkspace; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface UserWorkspaceRepository extends JpaRepository<UserWorkspace, Long> { |
| | | |
| | | UserWorkspace findByUserIdAndWorkspaceId(@Param("userId") Long userId, @Param("workspaceId") Long workspaceId); |
| | | |
| | | List<UserWorkspace> findByWorkspaceIdAndUseYn(@Param("workspaceId") Long workspaceId, @Param("useYn") Boolean useYn); |
| | | |
| | | @Query(name = "UserWorkspace.maxDisablePosition") |
| | | Long maxDisablePosition(@Param("workspaceId") Long workspaceId); |
| | | |
| | | List<UserWorkspace> findByWorkspaceIdAndManagerYn(@Param("workspaceId") Long workspaceId, @Param("managerYn") Boolean managerYn); |
| | | |
| | | UserWorkspace findByUserIdAndManagerYn(@Param("userId") Long userId, @Param("managerYn") Boolean managerYn); |
| | | |
| | | List<UserWorkspace> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | |
| | | List<UserWorkspace> findByWorkspaceIdAndUserIdIn(@Param("workspaceId") Long workspaceId, @Param("userIds") List<Long> userIds); |
| | | |
| | | } |
| | | |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Workflow; |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | |
| | | public interface WorkflowRepository extends JpaRepository<Workflow, Long> { |
| | | Workflow findByWorkspaceIdAndProjectType(@Param("workspaceId") Long workspaceId, @Param("projectType") ProjectType projectType); |
| | | |
| | | Workflow findByNameAndWorkspaceId(@Param("name") String name, @Param("workspaceId") Long workspaceId); |
| | | |
| | | Workflow findByNameAndWorkspaceIdAndIdNot(@Param("name") String name, @Param("workspaceId") Long workspaceId, @Param("id") Long id); |
| | | |
| | | List<Workflow> findByWorkspaceId(@Param("workspaceId") Long workspaceId); |
| | | |
| | | } |
| | | |
| | | |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.WorkflowStatus; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-03. |
| | | */ |
| | | public interface WorkflowStatusRepository extends JpaRepository<WorkflowStatus, Long> { |
| | | List<WorkflowStatus> findByProjectId(@Param("projectId") Long projectId); |
| | | // |
| | | // WorkflowStatus findByIdNotAndNameAndProjectId(@Param("id") Long id, @Param("name") String name, @Param("projectId") Long projectId); |
| | | // |
| | | // WorkflowStatus findByNameAndProjectId(@Param("name") String name, @Param("projectId") Long projectId); |
| | | // |
| | | // @Query(name="WorkflowStatus.findMaxPosition") |
| | | // Long findMaxPosition(@Param("projectId") Long projectId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.WorkflowTransition; |
| | | import kr.wisestone.owl.vo.WorkflowTransitionVo; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.List; |
| | | |
| | | public interface WorkflowTransitionRepository extends JpaRepository<WorkflowTransition, Long> { |
| | | List<WorkflowTransition> findByWorkflowId(@Param("workflowId") Long workflowId); |
| | | |
| | | @Query(name="WorkflowTransition.findBySourceIssueStatusIdAndWorkflowId") |
| | | List<WorkflowTransitionVo> findBySourceIssueStatusIdAndWorkflowId(@Param("sourceIssueStatusId") Long sourceIssueStatusId, @Param("workflowId") Long workflowId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.repository; |
| | | |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.data.jpa.repository.Query; |
| | | import org.springframework.data.repository.query.Param; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | public interface WorkspaceRepository extends JpaRepository<Workspace, Long> { |
| | | @Query(name="Workspace.findSubscribeImmediateExpireDate") |
| | | List<Workspace> findSubscribeImmediateExpireDate(@Param("todayFrom") Date todayFrom, @Param("todayTo") Date todayTo); |
| | | |
| | | @Query(name="Workspace.findExpireDate") |
| | | List<Workspace> findExpireDate(@Param("todayFrom") Date todayFrom, @Param("todayTo") Date todayTo); |
| | | |
| | | @Query(name = "Workspace.findByUserId") |
| | | List<Workspace> findByUserId(@Param("userId") Long userId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.scheduler; |
| | | |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.config.websocket.WebSocketService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | | import java.util.List; |
| | | |
| | | |
| | | @Component |
| | | public class Scheduler { |
| | | |
| | | /*private static final Logger log = LoggerFactory.getLogger(Scheduler.class); |
| | | |
| | | @Autowired |
| | | private PaymentService paymentService; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private SystemEmailService systemEmailService; |
| | | |
| | | @Autowired |
| | | private AttachedFileService attachedFileService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private WebSocketService webSocketService; |
| | | |
| | | // OWL ITS 관련자들에게 회원 가입 정보를 전달한다. |
| | | @Scheduled(cron = "0 0 17 * * *") |
| | | public void sendOwlManager() { |
| | | // OWL ITS 관련자들에게 회원 가입 정보를 전달한다. |
| | | this.userService.sendUserJoinStatisticsEmail(); |
| | | |
| | | // OWL ITS 관련자들에게 시스템 현황 정보를 전달한다. |
| | | this.userService.sendTotalStatisticsEmail(); |
| | | } |
| | | |
| | | @Scheduled(cron = "0 50 23 * * *") // 매 시간 (초, 분, 시, 일, 월, 년) |
| | | public void updateExchangeRatePayment() { |
| | | // 변경된 환율 정보를 결제 금액에 업데이트한다. |
| | | this.paymentService.updateExchangeRatePayment(); |
| | | } |
| | | |
| | | // 자동 결재 - 어제가 만료일인 업무 공간을 찾아서 결제한다. 새벽 1시에 실행 |
| | | @Scheduled(cron = "0 0 01 * * *") // 매 시간 (초, 분, 시, 일, 월, 년) |
| | | public void subscribePayment() { |
| | | List<Workspace> workspaces = this.workspaceService.findSubscribeImmediateExpireDate(); |
| | | |
| | | for (Workspace workspace : workspaces) { |
| | | this.paymentService.subscribeImmediate(workspace); |
| | | } |
| | | } |
| | | |
| | | // 이슈와 연결되지 않은 첨부파일 삭제 - 이슈 생성, 수정에서 에디트 창에 첨부했다가 저장하지 않은 파일들... 새벽 1시 30분에 실행 |
| | | @Scheduled(cron = "0 30 01 * * *") |
| | | public void deleteAttachedFileNotIdAndReservationIssue() { |
| | | // 이슈와 연결되지 않은 첨부파일 삭제 |
| | | this.attachedFileService.deleteAttachedFileNotId(); |
| | | // 이슈 예약 발생한 항목을 찾아 이슈를 다시 생성 상태로 변경한다. |
| | | this.issueService.reservationIssue(); |
| | | } |
| | | |
| | | // 업무 공간 자동 초기화 - 어제가 만료일인 업무 공간을 찾아서 업무 공간 사용자, 사용 용량을 초기화한다. 새벽 2시에 실행 |
| | | @Scheduled(cron = "0 0 02 * * *") |
| | | public void expireWorkspace() { |
| | | // 사용 기간이 만료된 업무 공간을 찾아 용량, 최대 사용자, 서비스 유형을 변경한다. |
| | | this.workspaceService.expireWorkspace(); |
| | | // 업무 공간 만료 예정 안내 |
| | | this.workspaceService.expireAlarmWorkspace(); |
| | | } |
| | | |
| | | // 이메일 예약 발송 - 사용자가 설정한 알림 시간에 시스템에서 일어난 이벤트를 이메일로 발송한다. - 매시간 30분에 실행 |
| | | @Scheduled(cron = "0 0/30 * * * *") |
| | | public void smartEmailSystem() { |
| | | // 예약된 이메일 발송 |
| | | this.systemEmailService.reservationSendEmail(); |
| | | } |
| | | |
| | | // 15초 마다 접속자 확인 |
| | | @Scheduled(fixedDelay = 15000) |
| | | public void pingUsers() { |
| | | // 접속 사용자를 확인한다. |
| | | this.webSocketService.checkActiveUser(); |
| | | }*/ |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.search; |
| | | |
| | | import kr.wisestone.owl.constant.ElasticSearchConstants; |
| | | import kr.wisestone.owl.util.ElasticSearchUtil; |
| | | import kr.wisestone.owl.vo.UserVo; |
| | | import org.elasticsearch.action.ActionListener; |
| | | import org.elasticsearch.action.index.IndexRequest; |
| | | import org.elasticsearch.action.index.IndexResponse; |
| | | import org.elasticsearch.action.support.WriteRequest; |
| | | import org.elasticsearch.client.RequestOptions; |
| | | import org.elasticsearch.client.RestHighLevelClient; |
| | | import org.elasticsearch.common.xcontent.XContentType; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | @Component |
| | | public class ElasticSearch { |
| | | private static final Logger log = LoggerFactory.getLogger(ElasticSearch.class); |
| | | |
| | | @Autowired |
| | | private RestHighLevelClient restHighLevelClient; |
| | | |
| | | /*// 사용자 시스템 사용 기록을 저장한다. |
| | | public void updateUserActiveHistory(HttpServletRequest httpServletRequest, UserVo userVo) { |
| | | IndexRequest request = new IndexRequest(ElasticSearchConstants.USER_SESSION_HISTORY_INDEX); |
| | | |
| | | request.source(ElasticSearchUtil.makeUserActiveHistoryDocument(httpServletRequest, userVo), XContentType.JSON); |
| | | request.timeout("5s"); |
| | | request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); |
| | | |
| | | try { |
| | | this.restHighLevelClient.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() { |
| | | @Override |
| | | public void onResponse(IndexResponse indexResponse) { |
| | | log.debug("사용자 시스템 사용 기록 인덱스 업데이트 성공"); |
| | | } |
| | | |
| | | @Override |
| | | public void onFailure(Exception ex) { |
| | | log.error("사용자 시스템 사용 기록 인덱스 업데이트 오류 : " + ex.getMessage()); |
| | | } |
| | | }); |
| | | } catch (Exception ex) { |
| | | log.error("사용자 시스템 사용 기록 인덱스 업데이트 오류 : " + ex.getMessage()); |
| | | } |
| | | }*/ |
| | | } |
New file |
| | |
| | | |
| | | package kr.wisestone.owl.service; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | public interface AbstractService<T, ID extends Serializable, R extends JpaRepository<T, ID>> { |
| | | long count(); |
| | | |
| | | void clear(); |
| | | |
| | | void detach(Object entity); |
| | | |
| | | void bulkInsert(List<T> entities); |
| | | |
| | | T findOne(ID id); |
| | | |
| | | List<T> findAll(List<ID> ids); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.AttachedFile; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.AttachedFileVo; |
| | | import kr.wisestone.owl.web.condition.AttachedFileCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface AttachedFileService extends AbstractService<AttachedFile, Long, JpaRepository<AttachedFile, Long>> { |
| | | |
| | | void addAttachedFile(List<Map<String, Object>> convertFileMaps, Issue issue, String userAccount); |
| | | |
| | | List<AttachedFile> addAttachedFile(List<MultipartFile> multipartFiles, Map<String, Object> content); |
| | | |
| | | List<AttachedFileVo> findAttachedFile(Map<String, Object> resJsonData, AttachedFileCondition condition); |
| | | |
| | | List<AttachedFile> findByIssueId(Long issueId); |
| | | |
| | | void connectIssueIdAttachedFile(Issue issue, IssueForm issueForm); |
| | | |
| | | AttachedFile getAttachedFile(Long attachedFileId); |
| | | |
| | | void removeAttachedFiles(List<Long> removeIds); |
| | | |
| | | void deleteWorkspaceCascadeAttachedFile(Workspace workspace); |
| | | |
| | | void deleteIssueCascadeAttachedFile(List<Long> issueIds, Workspace workspace); |
| | | |
| | | Long findUseStorage(Workspace workspace); |
| | | |
| | | ModelAndView checkUseWorkspaceTraffic(Long id, Model model); |
| | | |
| | | void deleteAttachedFileNotId(); |
| | | |
| | | String uploadFile(Map<String, Object> convertFileMap, String awsUploadFolder, String userAccount, int totalFileCount, int uploadFileCount); |
| | | |
| | | void removeFile(String key, Long workspaceId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.CustomField; |
| | | import kr.wisestone.owl.vo.CustomFieldVo; |
| | | import kr.wisestone.owl.web.condition.CustomFieldCondition; |
| | | import kr.wisestone.owl.web.form.CustomFieldForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface CustomFieldService extends AbstractService<CustomField, Long, JpaRepository<CustomField, Long>>{ |
| | | |
| | | CustomField addCustomField(CustomFieldForm customFieldForm); |
| | | |
| | | List<CustomFieldVo> findCustomField(Map<String, Object> resJsonData, |
| | | CustomFieldCondition condition, Pageable pageable); |
| | | |
| | | void detailCustomField(Map<String, Object> resJsonData, CustomFieldCondition customFieldCondition); |
| | | |
| | | CustomField modifyCustomField(CustomFieldForm customFieldForm); |
| | | |
| | | CustomField getCustomField(Long id); |
| | | |
| | | void removeCustomFields(CustomFieldForm customFieldForm); |
| | | |
| | | CustomField findByName(String name); |
| | | |
| | | ModelAndView downloadExcel(HttpServletRequest request, Model model); |
| | | |
| | | List<CustomField> findByWorkspaceId(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.CustomField; |
| | | import kr.wisestone.owl.domain.CustomFieldValue; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import java.util.List; |
| | | |
| | | public interface CustomFieldValueService extends AbstractService<CustomFieldValue, Long, JpaRepository<CustomFieldValue, Long>>{ |
| | | |
| | | void addCustomFieldValues(CustomField customField, List<String> values, CustomFieldType oldCustomFieldType); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Event; |
| | | import kr.wisestone.owl.vo.EventVo; |
| | | import kr.wisestone.owl.web.condition.EventCondition; |
| | | import kr.wisestone.owl.web.form.EventForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface EventService extends AbstractService<Event, Long, JpaRepository<Event, Long>> { |
| | | Event addEvent(EventForm eventForm); |
| | | |
| | | List<EventVo> findEvent(Map<String, Object> resJsonData, |
| | | EventCondition eventCondition, Pageable pageable); |
| | | |
| | | Event getEvent(Long id); |
| | | |
| | | Event modifyEvent(EventForm eventForm); |
| | | Event activeEvent(EventForm eventForm); |
| | | |
| | | void detailEvent(Map<String, Object> resJsonData, EventCondition eventCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Faq; |
| | | import kr.wisestone.owl.domain.Guide; |
| | | import kr.wisestone.owl.vo.FaqVo; |
| | | import kr.wisestone.owl.web.condition.FaqCondition; |
| | | import kr.wisestone.owl.web.form.FaqForm; |
| | | import kr.wisestone.owl.web.form.GuideForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface FaqService extends AbstractService<Faq, Long, JpaRepository<Faq, Long>> { |
| | | Faq addFaq(FaqForm faqForm); |
| | | |
| | | List<FaqVo> findFaq(Map<String, Object> resJsonData, |
| | | FaqCondition faqCondition, Pageable pageable); |
| | | |
| | | Faq getFaq(Long id); |
| | | |
| | | Faq modifyFaq(FaqForm faqForm); |
| | | Faq activeFaq(FaqForm faqForm); |
| | | |
| | | void detailFaq(Map<String, Object> resJsonData, FaqCondition faqCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueType; |
| | | import kr.wisestone.owl.domain.Workflow; |
| | | import kr.wisestone.owl.vo.IssueVo; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface GanttService extends AbstractService<Issue, Long, JpaRepository<Issue, Long>>{ |
| | | |
| | | void addIssueVersion(Long id); |
| | | |
| | | Issue addIssue(IssueForm issueForm, List<MultipartFile> files); |
| | | |
| | | List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | IssueCondition condition, Pageable pageable); |
| | | |
| | | List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | ProjectCondition projectCondition, Pageable pageable); |
| | | |
| | | void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition); |
| | | |
| | | Issue modifyIssue(IssueForm issueForm, List<MultipartFile> files); |
| | | |
| | | void removeIssues(IssueForm issueForm); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Guide; |
| | | import kr.wisestone.owl.vo.GuideVo; |
| | | import kr.wisestone.owl.web.condition.GuideCondition; |
| | | import kr.wisestone.owl.web.form.GuideForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface GuideService extends AbstractService<Guide, Long, JpaRepository<Guide, Long>> { |
| | | Guide addGuide(GuideForm guideForm); |
| | | |
| | | List<GuideVo> findGuide(Map<String, Object> resJsonData, |
| | | GuideCondition guideCondition, Pageable pageable); |
| | | |
| | | Guide getGuide(Long id); |
| | | |
| | | Guide modifyGuide(GuideForm guideForm); |
| | | Guide activeGuide(GuideForm guideForm); |
| | | |
| | | void detailGuide(Map<String, Object> resJsonData, GuideCondition guideCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueComment; |
| | | import kr.wisestone.owl.vo.IssueCommentVo; |
| | | import kr.wisestone.owl.web.form.IssueCommentForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface IssueCommentService extends AbstractService<IssueComment, Long, JpaRepository<IssueComment, Long>> { |
| | | |
| | | IssueComment addIssueComment(IssueCommentForm issueCommentForm); |
| | | |
| | | void removeIssueComments(IssueCommentForm issueCommentForm); |
| | | |
| | | IssueComment getIssueComment(Long id ); |
| | | |
| | | List<IssueCommentVo> findIssueComment(Long issueId); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.CustomField; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueCustomFieldValue; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.vo.IssueCustomFieldValueVo; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | public interface IssueCustomFieldValueService extends AbstractService<IssueCustomFieldValue, Long, JpaRepository<IssueCustomFieldValue, Long>>{ |
| | | void modifyIssueCustomFieldValue(Issue issue, List<Map<String, Object>> issueCustomFields); |
| | | |
| | | void getCustomFieldAndIssueTypeCustomField(Map<String, Object> map, Issue issue, Map<String, Object> result); |
| | | |
| | | List<IssueCustomFieldValueVo> findByIssueId(Long issueId); |
| | | |
| | | void checkExistIssueCustomFieldValue(CustomField customField, List<String> values, CustomFieldType oldCustomFieldType); |
| | | |
| | | List<IssueCustomFieldValue> findByCustomFieldId(CustomField customField); |
| | | |
| | | void removeIssueCustomFieldValue(Long issueTypeCustomFieldId); |
| | | |
| | | boolean find(IssueCondition condition, Set<String> issueIds); |
| | | |
| | | List<Map<String, Object>> findInIssueIds(IssueCondition issueCondition); |
| | | |
| | | void removeIssueCustomFieldValuesByCustomFieldId(CustomField customField); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.IssueHistoryType; |
| | | import kr.wisestone.owl.service.impl.IssueHistoryServiceImpl; |
| | | import kr.wisestone.owl.vo.IssueHistoryVo; |
| | | import kr.wisestone.owl.web.condition.IssueHistoryCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | |
| | | public interface IssueHistoryService extends AbstractService<IssueHistory, Long, JpaRepository<IssueHistory, Long>>{ |
| | | |
| | | void addIssueHistory(Issue issue, IssueHistoryType issueHistoryType, String issueChangeDescription); |
| | | |
| | | void makeDescription(StringBuilder description, IssueHistoryType issueHistoryType, String issueChangeDescription); |
| | | |
| | | void findIssueHistory(Map<String, Object> resJsonData, IssueHistoryCondition issueHistoryCondition); |
| | | |
| | | List<IssueHistoryVo> findIssueHistory(Long issueId); |
| | | |
| | | StringBuilder detectIssueChange(Issue issue, IssueForm issueForm, Project project, IssueStatus issueStatus, IssueType issueType, Priority priority, Severity severity, List<MultipartFile> files); |
| | | |
| | | void detectProject(Issue issue, IssueForm issueForm, StringBuilder description, Project project); |
| | | |
| | | void detectIssueSeverity(Issue issue, IssueForm issueForm, StringBuilder description, Severity severity); |
| | | |
| | | void detectIssuePriority(Issue issue, IssueForm issueForm, StringBuilder description, Priority priority); |
| | | |
| | | void detectIssueStatus(Issue issue, IssueForm issueForm, StringBuilder description, IssueStatus issueStatus); |
| | | |
| | | void detectReservationIssueStatus(Issue issue, StringBuilder description, IssueStatus issueStatus); |
| | | |
| | | void recordRemoveWorkflowToIssueStatus(String oldIssueStatusName, String newIssueStatusName, StringBuilder description); |
| | | |
| | | void detectIssueType(Issue issue, IssueForm issueForm, StringBuilder description, IssueType issueType); |
| | | |
| | | void detectIssuePeriod(Issue issue, IssueForm issueForm, StringBuilder description); |
| | | |
| | | void detectIssueManager(Issue issue, IssueForm issueForm, StringBuilder description); |
| | | |
| | | void detectAttachedFile(IssueForm issueForm, StringBuilder description, List<MultipartFile> files); |
| | | |
| | | void detectCustomField(Issue issue, IssueForm issueForm, StringBuilder description); |
| | | |
| | | void detectRelationIssue(IssueHistoryType type, IssueRelation issueRelation, StringBuilder description); |
| | | |
| | | void recodeRemoveCustomFieldOptionValue(CustomField customField, String oldValue, String newValue, StringBuilder description); |
| | | |
| | | void recodeChangeCustomFieldType(CustomField customField, String oldValue, StringBuilder description); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueNumberGenerator; |
| | | import kr.wisestone.owl.domain.Project; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public interface IssueNumberGeneratorService extends AbstractService<IssueNumberGenerator, Long, JpaRepository<IssueNumberGenerator, Long>>{ |
| | | Long generateIssueNumber(Project project); |
| | | |
| | | void updateIssueNumber(Map<Long, Long> issueNumberMaps); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueRelation; |
| | | import kr.wisestone.owl.vo.IssueRelationVo; |
| | | import kr.wisestone.owl.vo.IssueVo; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueRelationCondition; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface IssueRelationService extends AbstractService<IssueRelation, Long, JpaRepository<IssueRelation, Long>>{ |
| | | void addRelationIssue(Map<String, Object> resJsonData, IssueRelationCondition condition); |
| | | List<IssueVo> findRelationIssue(Map<String, Object> resJsonData, |
| | | IssueRelationCondition condition, Pageable pageable); |
| | | |
| | | List<IssueVo> findRelationIssue(Long issueId); |
| | | |
| | | boolean removeRelationIssue(Map<String, Object> resJsonData, IssueRelationCondition condition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueReservation; |
| | | import kr.wisestone.owl.web.condition.IssueReservationCondition; |
| | | import kr.wisestone.owl.web.form.IssueReservationForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface IssueReservationService extends AbstractService<IssueReservation, Long, JpaRepository<IssueReservation, Long>>{ |
| | | |
| | | void detailIssueReservation(Map<String, Object> resJsonData, IssueReservationCondition issueReservationCondition); |
| | | |
| | | IssueReservation getIssueReservation(Long id); |
| | | |
| | | void modifyIssueReservation(Map<String, Object> resJsonData, IssueReservationForm issueReservationForm); |
| | | |
| | | List<IssueReservation> findByIssueReservationTypeNotNull(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueRisk; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface IssueRiskService extends AbstractService<IssueRisk, Long, JpaRepository<IssueRisk, Long>>{ |
| | | |
| | | IssueRisk addIssueRisk(Issue issue, Workspace workspace); |
| | | |
| | | void modifyIssueRisk(Issue issue, Boolean changeIssueStatus, Boolean changeAssignee, Long issueStatusId); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueSearch; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public interface IssueSearchService extends AbstractService<IssueSearch, Long, JpaRepository<IssueSearch, Long>>{ |
| | | IssueSearch addIssueSearch(Map<String, Object> params); |
| | | |
| | | IssueSearch findByUserIdAndWorkspaceId(); |
| | | |
| | | void detailIssueSearch(Map<String, Object> resJsonData); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueType; |
| | | import kr.wisestone.owl.domain.Workflow; |
| | | import kr.wisestone.owl.vo.IssueVo; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface IssueService extends AbstractService<Issue, Long, JpaRepository<Issue, Long>>{ |
| | | |
| | | void addIssueVersion(Long id); |
| | | |
| | | Issue addIssue(IssueForm issueForm, List<MultipartFile> files); |
| | | |
| | | List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | IssueCondition condition, Pageable pageable); |
| | | |
| | | List<IssueVo> findChartIssue(Map<String, Object> resJsonData, |
| | | IssueCondition condition, Pageable pageable); |
| | | |
| | | List<IssueVo> findChartIssue(Map<String, Object> resJsonData, |
| | | ProjectCondition condition, Pageable pageable); |
| | | |
| | | void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition); |
| | | |
| | | Issue modifyIssue(IssueForm issueForm, List<MultipartFile> files); |
| | | |
| | | void removeIssues(IssueForm issueForm); |
| | | |
| | | void modifyIssueStatus(IssueForm issueForm); |
| | | |
| | | Issue getIssue(Long taskId); |
| | | |
| | | long countByIssueTypeId(Long issueTypeId); |
| | | |
| | | long countByIssueStatus(Long issueStatusId); |
| | | |
| | | void changeWorkflows(Workflow workflow, IssueType issueType); |
| | | |
| | | ModelAndView downloadExcel(HttpServletRequest request, Model model); |
| | | |
| | | void modifyMultiIssueStatus(IssueForm issueForm); |
| | | |
| | | void modifyIssueUser(IssueForm issueForm); |
| | | |
| | | ModelAndView downloadExcelTemplate(HttpServletRequest request, Model model); |
| | | |
| | | void importExcel(MultipartFile multipartFile) throws Exception; |
| | | |
| | | List<Long> findByProjectId(Long projectId); |
| | | |
| | | void setIssueDetail(IssueVo issueVo, Issue issue); |
| | | |
| | | void sendIssueEmail(IssueForm issueForm); |
| | | |
| | | void reservationIssue(); |
| | | |
| | | Map<String, Object> findTask(IssueCondition taskCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueStatus; |
| | | import kr.wisestone.owl.domain.Workflow; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.IssueStatusVo; |
| | | import kr.wisestone.owl.web.condition.IssueStatusCondition; |
| | | import kr.wisestone.owl.web.form.IssueStatusForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface IssueStatusService extends AbstractService<IssueStatus, Long, JpaRepository<IssueStatus, Long>>{ |
| | | |
| | | List<IssueStatus> addDefaultIssueStatus(Workspace workspace); |
| | | |
| | | List<IssueStatus> findByWorkspaceId(Long workspaceId); |
| | | |
| | | IssueStatus addIssueStatus(IssueStatusForm issueStatusForm); |
| | | |
| | | List<IssueStatusVo> findIssueStatus(Map<String, Object> resJsonData, |
| | | IssueStatusCondition issueStatusCondition, Pageable pageable); |
| | | |
| | | List<IssueStatusVo> findIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition condition); |
| | | |
| | | void findNextIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition condition); |
| | | |
| | | void detailIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition issueStatusCondition); |
| | | |
| | | IssueStatus modifyIssueStatus(IssueStatusForm issueStatusForm); |
| | | |
| | | IssueStatus getIssueStatus(Long id); |
| | | |
| | | void removeIssueStatus(IssueStatusForm issueStatusForm); |
| | | |
| | | List<IssueStatusVo> findByWorkflowId(Long workflowId); |
| | | |
| | | IssueStatus findByIssueStatusTypeIsReady(Workflow workflow); |
| | | |
| | | void checkNextIssueStatus(Issue issue, IssueStatus nextIssueStatus); |
| | | |
| | | ModelAndView downloadExcel(HttpServletRequest request, Model model); |
| | | |
| | | void findNextMultiIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition condition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueTableConfig; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import java.util.Map; |
| | | |
| | | public interface IssueTableConfigService extends AbstractService<IssueTableConfig, Long, JpaRepository<IssueTableConfig, Long>> { |
| | | |
| | | IssueTableConfig addIssueTableConfig(Map<String, Object> params); |
| | | |
| | | IssueTableConfig findByUserIdAndWorkspaceId(); |
| | | |
| | | void detailIssueTableConfig(Map<String, Object> resJsonData); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueTypeCustomField; |
| | | import kr.wisestone.owl.vo.IssueTypeCustomFieldVo; |
| | | import kr.wisestone.owl.web.condition.IssueTypeCustomFieldCondition; |
| | | import kr.wisestone.owl.web.form.IssueTypeCustomFieldForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface IssueTypeCustomFieldService extends AbstractService<IssueTypeCustomField, Long, JpaRepository<IssueTypeCustomField, Long>>{ |
| | | |
| | | void modifyIssueTypeCustomFields(IssueTypeCustomFieldForm issueTypeCustomFieldForm); |
| | | |
| | | List<IssueTypeCustomFieldVo> findIssueTypeCustomField(Map<String, Object> resJsonData, IssueTypeCustomFieldCondition condition); |
| | | |
| | | List<IssueTypeCustomField> findByProjectIdAndIssueTypeId(Long projectId, Long issueTypeId); |
| | | |
| | | IssueTypeCustomField findByProjectIdAndIssueTypeIdAndCustomFieldId(Long projectId, Long issueTypeId, Long customFieldId); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueType; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import kr.wisestone.owl.vo.IssueTypeVo; |
| | | import kr.wisestone.owl.web.condition.IssueTypeCondition; |
| | | import kr.wisestone.owl.web.form.IssueTypeForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | public interface IssueTypeService extends AbstractService<IssueType, Long, JpaRepository<IssueType, Long>>{ |
| | | |
| | | void addDefaultIssueType(Workspace workspace, List<ProjectType> projectTypes); |
| | | |
| | | IssueType addIssueType(IssueTypeForm issueTypeForm); |
| | | |
| | | List<IssueTypeVo> findIssueType(Map<String, Object> resJsonData, |
| | | IssueTypeCondition condition, Pageable pageable); |
| | | |
| | | void detailIssueType(Map<String, Object> resJsonData, IssueTypeCondition issueTypeCondition); |
| | | |
| | | IssueType modifyIssueType(IssueTypeForm issueTypeForm); |
| | | |
| | | IssueType getIssueType(Long id); |
| | | |
| | | void removeIssueTypes(IssueTypeForm issueTypeForm); |
| | | |
| | | List<IssueType> findByWorkspaceId(); |
| | | |
| | | ModelAndView downloadExcel(HttpServletRequest request, Model model); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueUser; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface IssueUserService extends AbstractService<IssueUser, Long, JpaRepository<IssueUser, Long>>{ |
| | | void modifyIssueUser(Issue issue, Workspace workspace, List<Long> userIds); |
| | | |
| | | void insertIssueUser(List<Map<String, Long>> issueAssigneeMaps); |
| | | |
| | | void removeIssueUser(Long projectId, List<Long> excludeUserIds); |
| | | |
| | | List<IssueUser> find(Issue issue); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueVersion; |
| | | import kr.wisestone.owl.web.condition.IssueVersionCondition; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.Map; |
| | | |
| | | |
| | | public interface IssueVersionService extends AbstractService<IssueVersion, Long, JpaRepository<IssueVersion, Long>>{ |
| | | |
| | | void addIssueVersion(Issue issue); |
| | | |
| | | void find(Map<String, Object> resJsonData, IssueVersionCondition issueVersionCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.UserWorkspace; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.ManageUserVo; |
| | | import kr.wisestone.owl.vo.UserWorkspaceVo; |
| | | import kr.wisestone.owl.web.condition.UserWorkspaceCondition; |
| | | import kr.wisestone.owl.web.form.ManageUserForm; |
| | | import kr.wisestone.owl.web.form.UserWorkspaceForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface ManageUserService extends AbstractService<UserWorkspace, Long, JpaRepository<UserWorkspace, Long>> { |
| | | |
| | | List<ManageUserVo> findUserPermission(Map<String, Object> resJsonData, |
| | | UserWorkspaceCondition condition, Pageable pageable); |
| | | |
| | | void modifyUserPermission(ManageUserForm manageUserForm); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Notice; |
| | | import kr.wisestone.owl.vo.NoticeVo; |
| | | import kr.wisestone.owl.web.condition.NoticeCondition; |
| | | import kr.wisestone.owl.web.form.NoticeForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface NoticeService extends AbstractService<Notice, Long, JpaRepository<Notice, Long>> { |
| | | Notice addNotice(NoticeForm noticeForm); |
| | | |
| | | List<NoticeVo> findNotice(Map<String, Object> resJsonData, |
| | | NoticeCondition noticeCondition, Pageable pageable); |
| | | |
| | | Notice getNotice(Long id); |
| | | |
| | | Notice modifyNotice(NoticeForm noticeForm); |
| | | |
| | | void detailNotice(Map<String, Object> resJsonData, NoticeCondition noticeCondition); |
| | | |
| | | void sendNotice(NoticeForm noticeForm); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.PaymentHistory; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.service.impl.PaymentServiceImpl; |
| | | import kr.wisestone.owl.web.form.PaymentForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface PaymentHistoryService extends AbstractService<PaymentHistory, Long, JpaRepository<PaymentHistory, Long>>{ |
| | | PaymentHistory addPaymentHistory(PaymentServiceImpl.RestClientResultObject resultObject, PaymentForm paymentForm, Workspace workspace); |
| | | |
| | | PaymentHistory cancelPaymentHistory(PaymentForm paymentForm, Workspace workspace, String reason); |
| | | |
| | | PaymentHistory findByWorkspaceLastPaymentHistory(Workspace workspace); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Payment; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.PaymentVo; |
| | | import kr.wisestone.owl.web.form.PaymentForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public interface PaymentService extends AbstractService<Payment, Long, JpaRepository<Payment, Long>>{ |
| | | String getAccessToken(); |
| | | |
| | | void immediateAddUser(PaymentForm paymentForm); |
| | | |
| | | void paymentOneTime(PaymentForm paymentForm); |
| | | |
| | | void cancelNextPayment(PaymentForm paymentForm); |
| | | |
| | | void detailPayment(Map<String, Object> resJsonData, PaymentForm paymentForm); |
| | | |
| | | PaymentVo modifyPayment(PaymentForm paymentForm); |
| | | |
| | | void subscribeImmediate(Workspace workspace); |
| | | |
| | | Payment getPayment(Long id); |
| | | |
| | | void updateExchangeRatePayment(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Permission; |
| | | import kr.wisestone.owl.vo.PermissionVo; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface PermissionService extends AbstractService<Permission, Long, JpaRepository<Permission, Long>>{ |
| | | List<PermissionVo> findByUserId(); |
| | | |
| | | List<Permission> findByRoleType(String roleType); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Priority; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.PriorityVo; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface PriorityService extends AbstractService<Priority, Long, JpaRepository<Priority, Long>>{ |
| | | List<Priority> findByWorkspaceIdOrderByPosition(); |
| | | |
| | | Priority getPriority(Long id); |
| | | |
| | | List<PriorityVo> findPriority(Map<String, Object> resJsonData); |
| | | |
| | | void addDefaultPriority(Workspace workspace); |
| | | |
| | | List<Priority> findByWorkspaceId(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.ProjectClosure; |
| | | import kr.wisestone.owl.domain.ProjectRole; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface ProjectClosureService extends AbstractService<ProjectClosure, Long, JpaRepository<ProjectClosure, Long>>{ |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.ProjectRole; |
| | | import kr.wisestone.owl.domain.ProjectRolePermission; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface ProjectRolePermissionService extends AbstractService<ProjectRolePermission, Long, JpaRepository<ProjectRolePermission, Long>>{ |
| | | |
| | | void addDefaultProjectRoleAssociatedPermissions(ProjectRole projectRole, String roleType); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Project; |
| | | import kr.wisestone.owl.domain.ProjectRole; |
| | | import kr.wisestone.owl.domain.User; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface ProjectRoleService extends AbstractService<ProjectRole, Long, JpaRepository<ProjectRole, Long>>{ |
| | | |
| | | void addDefaultProjectRole(Project project, List<User> managers, List<User> users); |
| | | |
| | | ProjectRole findByProjectIdAndRoleType(Long projectId, String roleType); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Project; |
| | | import kr.wisestone.owl.domain.ProjectRoleUser; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface ProjectRoleUserService extends AbstractService<ProjectRoleUser, Long, JpaRepository<ProjectRoleUser, Long>>{ |
| | | List<ProjectRoleUser> findByProjectRoleId(Long projectRoleId); |
| | | |
| | | ProjectRoleUser findByProjectRoleIdAndUserId(Long projectRoleId, Long userId); |
| | | |
| | | void withDrawWorkspaceManagerModifyProjectRole(Workspace workspace, User user); |
| | | |
| | | List<Map<String, Object>> findProjectRoleUser(Map<String, Object> projectRoleUserMap); |
| | | |
| | | boolean checkProjectManager(Project project); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Project; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.ProjectVo; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.ProjectForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface ProjectService extends AbstractService<Project, Long, JpaRepository<Project, Long>>{ |
| | | |
| | | Project addDefaultProject(User user, Workspace workspace); |
| | | |
| | | Project addProject(ProjectForm projectForm); |
| | | |
| | | List<ProjectVo> findProject(Map<String, Object> resJsonData, |
| | | ProjectCondition condition, Pageable pageable); |
| | | |
| | | void detailProject(Map<String, Object> resJsonData, ProjectCondition projectCondition); |
| | | |
| | | Project findByProjectKey(String projectKey); |
| | | |
| | | Project modifyProject(ProjectForm projectForm); |
| | | |
| | | Project getProject(Long id); |
| | | |
| | | void removeProjects(ProjectForm projectForm); |
| | | |
| | | List<Project> findByWorkspaceId(); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceIdAndIncludeProject(List<String> statuses, String projectType); |
| | | List<Map<String, Object>> findByWorkspaceIdAndIncludeProject(ProjectCondition projectCondition); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceIdAndIncludeProjectAll(List<String> statuses, String projectType); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceManagerAll(); |
| | | |
| | | List<Map<String, Object>> findByWorkspaceIdAndIncludeProjectAll(ProjectCondition projectCondition); |
| | | |
| | | List<ProjectVo> findByIncludeProject(List<String> statuses, String projectType); |
| | | |
| | | ModelAndView downloadExcel(HttpServletRequest request, Model model); |
| | | |
| | | void findLastUseProject(Map<String, Object> resJsonData); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Qna; |
| | | import kr.wisestone.owl.vo.QnaVo; |
| | | import kr.wisestone.owl.web.condition.QnaCondition; |
| | | import kr.wisestone.owl.web.form.QnaForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface QnaService extends AbstractService<Qna, Long, JpaRepository<Qna, Long>> { |
| | | Qna addQna(QnaForm qnaForm); |
| | | |
| | | List<QnaVo> findQna(Map<String, Object> resJsonData, |
| | | QnaCondition qnaCondition, Pageable pageable); |
| | | |
| | | Qna getQna(Long id); |
| | | |
| | | Qna modifyQna(QnaForm qnaForm); |
| | | |
| | | void detailQna(Map<String, Object> resJsonData, QnaCondition qnaCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Payment; |
| | | import kr.wisestone.owl.domain.ReservationDisableUser; |
| | | import kr.wisestone.owl.web.form.PaymentForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public interface ReservationDisableUserService extends AbstractService<ReservationDisableUser, Long, JpaRepository<ReservationDisableUser, Long>>{ |
| | | void add(PaymentForm paymentForm, Payment payment); |
| | | |
| | | void findReservationDisableUser(Map<String, Object> params, Map<String, Object> resJsonData); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Severity; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.SeverityVo; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface SeverityService extends AbstractService<Severity, Long, JpaRepository<Severity, Long>>{ |
| | | List<Severity> findByWorkspaceIdOrderByPosition(); |
| | | |
| | | Severity getSeverity(Long id); |
| | | |
| | | List<SeverityVo> findSeverity(Map<String, Object> resJsonData); |
| | | |
| | | void addDefaultSeverity(Workspace workspace); |
| | | |
| | | List<Severity> findByWorkspaceId(); |
| | | } |
| | | |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.SystemEmail; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.enumType.EmailType; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface SystemEmailService extends AbstractService<SystemEmail, Long, JpaRepository<SystemEmail, Long>>{ |
| | | |
| | | void directEmail(String[] sendUsers, EmailType emailType, Map<String, Object> content, String toUser); |
| | | |
| | | void sendEmail(String subject, String content, String[] to, String[] filePaths); |
| | | |
| | | List<String> notificationUserChange(List<User> totalUsers, List<User> targetUsers); |
| | | |
| | | void reservationEmail(String[] sendUsers, EmailType emailType, Map<String, Object> params); |
| | | |
| | | List<SystemEmail> findBySendAddressAndSendYn(String sendAddress); |
| | | |
| | | void reservationSendEmail(); |
| | | |
| | | void information(Map<String, Object> params); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.SystemRole; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface SystemRoleService extends AbstractService<SystemRole, Long, JpaRepository<SystemRole, Long>>{ |
| | | SystemRole findByRoleType(String roleType); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.UserHistory; |
| | | import kr.wisestone.owl.web.condition.UserHistoryCondition; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public interface UserHistoryService extends AbstractService<UserHistory, Long, JpaRepository<UserHistory, Long>>{ |
| | | void addUserHistory(Map<String, Object> resJsonData, UserHistoryCondition userHistoryCondition); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.UserInvite; |
| | | import kr.wisestone.owl.domain.UserInviteProject; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface UserInviteProjectService extends AbstractService<UserInviteProject, Long, JpaRepository<UserInviteProject, Long>> { |
| | | List<UserInviteProject> addUserInviteProject(List<Long> projectIds, UserInvite userInvite); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.UserInvite; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.web.form.UserInviteForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface UserInviteService extends AbstractService<UserInvite, Long, JpaRepository<UserInvite, Long>> { |
| | | void inviteWorkspace(UserInviteForm userInviteForm); |
| | | |
| | | void checkInviteUser(User user); |
| | | |
| | | void deleteUserInvite(Long workspaceId, List<String> email); |
| | | |
| | | void includePrimaryWorkspace(User user, Workspace workspace); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Project; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.domain.enumType.SocialType; |
| | | import kr.wisestone.owl.vo.UserVo; |
| | | import kr.wisestone.owl.web.condition.UserCondition; |
| | | import kr.wisestone.owl.web.form.UserForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface UserService extends AbstractService<User, Long, JpaRepository<User, Long>> { |
| | | |
| | | User findByAccount(String account); |
| | | |
| | | User addUser(UserForm userForm, MultipartFile profile); |
| | | |
| | | List<UserVo> findUser(Map<String, Object> resJsonData, |
| | | UserCondition condition, Pageable pageable); |
| | | |
| | | List<User> findAdmin(); |
| | | |
| | | User getUser(Long userId); |
| | | |
| | | void detailUser(Map<String, Object> resJsonData, UserCondition userCondition); |
| | | |
| | | void modifyUser(UserForm userForm, MultipartFile profile); |
| | | |
| | | void modifyPassword(UserForm userForm); |
| | | |
| | | void returnEmailPassword(UserForm userForm); |
| | | |
| | | ModelAndView getOAuthToken(String code, String state, SocialType socialType, HttpServletRequest request); |
| | | |
| | | List<User> findByIdIn(List<Long> userIds); |
| | | |
| | | void updateLastDefaultWorkspace(Workspace workspace, User user); |
| | | |
| | | User findByWorkspaceIdAndManagerYn(Workspace workspace); |
| | | |
| | | void updateLastWorkspace(Map<String, Object> resJsonData, UserForm userForm); |
| | | |
| | | void updateLastProject(Map<String, Object> resJsonData, UserForm userForm); |
| | | |
| | | void updateLastMyWorkspace(User user); |
| | | |
| | | void findProjectMember(Map<String, Object> resJsonData, UserCondition userCondition); |
| | | |
| | | void withDrawUser(); |
| | | |
| | | void autoLogin(String email, HttpServletRequest request); |
| | | |
| | | void updateUserSession(); |
| | | |
| | | User getUserSession(Map<String, Object> resJsonData, HttpServletRequest httpServletRequest); |
| | | |
| | | List<String> findByReservationNotifyTime(); |
| | | |
| | | List<Map<String, Object>> findProjectMember(Project project); |
| | | |
| | | void updateLanguage(String language); |
| | | |
| | | void sendUserJoinStatisticsEmail(); |
| | | |
| | | void sendTotalStatisticsEmail(); |
| | | |
| | | List<UserVo> findByAllWorkspace(Map<String, Object> resJsonData, UserCondition condition, Pageable pageable); |
| | | |
| | | ModelAndView downloadExcel(Model model); |
| | | |
| | | UserVo removeSensitiveUser(Long userId); |
| | | |
| | | void updateLastLogin(); |
| | | |
| | | //ModelAndView downloadExcelEvent(Model model); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.UserWithDraw; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | public interface UserWithDrawService extends AbstractService<UserWithDraw, Long, JpaRepository<UserWithDraw, Long>> { |
| | | void addUserWithDraw(User user); |
| | | |
| | | UserWithDraw findByAccount(String account); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.UserWorkspace; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.vo.UserWorkspaceVo; |
| | | import kr.wisestone.owl.web.condition.UserWorkspaceCondition; |
| | | import kr.wisestone.owl.web.form.UserWorkspaceForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface UserWorkspaceService extends AbstractService<UserWorkspace, Long, JpaRepository<UserWorkspace, Long>> { |
| | | |
| | | UserWorkspace addUserWorkspace(User user, Workspace workspace, Boolean managerYn, Boolean useYn); |
| | | |
| | | List<UserWorkspaceVo> findUserWorkspace(Map<String, Object> resJsonData, |
| | | UserWorkspaceCondition condition, Pageable pageable); |
| | | |
| | | void modifyUserWorkspace(UserWorkspaceForm userWorkspaceForm); |
| | | |
| | | UserWorkspace findByUserIdAndWorkspaceId(Long userId, Long workspaceId); |
| | | |
| | | Integer countByWorkspaceIdAndUseYn(Long workspaceId, Boolean useYn); |
| | | |
| | | List<UserWorkspace> findByWorkspaceIdAndUseYn(Long workspaceId, Boolean useYn); |
| | | |
| | | List<UserWorkspace> findByWorkspaceIdAndManagerYn(Long workspaceId, Boolean managerYn); |
| | | |
| | | UserWorkspace findMyWorkspace(Long userId); |
| | | |
| | | void disabledUserWorkspace(User user, Workspace workspace); |
| | | |
| | | UserWorkspace getUserWorkspace(Long id); |
| | | |
| | | boolean checkWorkspaceManager(); |
| | | |
| | | List<UserWorkspace> findByWorkspaceId(Long workspaceId); |
| | | |
| | | void limitExpireUserWorkspace(Workspace workspace); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.condition.WidgetCondition; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface WidgetService { |
| | | |
| | | WidgetCondition makeWidgetCondition(); |
| | | |
| | | void findAllWidget(Map<String, Object> resJsonData); |
| | | |
| | | void findStatisticsIssue(Map<String, Object> resJsonData, WidgetCondition widgetCondition); |
| | | |
| | | void findProjectProgress(Map<String, Object> resJsonData, WidgetCondition widgetCondition); |
| | | |
| | | void findMyAssigneeIssue(Map<String, Object> resJsonData, WidgetCondition widgetCondition, Pageable pageable); |
| | | |
| | | void findDelayIssue(Map<String, Object> resJsonData, WidgetCondition widgetCondition, Pageable pageable); |
| | | |
| | | void findRegisterIssue(Map<String, Object> resJsonData, WidgetCondition widgetCondition, Pageable pageable); |
| | | |
| | | void findMemberProgress(Map<String, Object> resJsonData, WidgetCondition widgetCondition, Boolean getWidgetCondition); |
| | | |
| | | void findMyIssueDetail(Map<String, Object> resJsonData, WidgetCondition widgetCondition); |
| | | |
| | | void findRiskIssue(Map<String, Object> resJsonData, WidgetCondition widgetCondition, Pageable pageable); |
| | | |
| | | void findIssueComplete(Map<String, Object> resJsonData, WidgetCondition widgetCondition, String searchPeriod); |
| | | |
| | | void findByStandIssueStatus(Map<String, Object> resJsonData, WidgetCondition widgetCondition); |
| | | |
| | | void findByStandIssueType(Map<String, Object> resJsonData, WidgetCondition widgetCondition, Boolean getWidgetCondition); |
| | | |
| | | void findSeverityIssueWidget(Map<String, Object> resJsonData, WidgetCondition widgetCondition, Map<String, Object> parameter, Pageable pageable); |
| | | |
| | | ModelAndView downloadExcel(HttpServletRequest request, Model model); |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.Workflow; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import kr.wisestone.owl.vo.WorkflowVo; |
| | | import kr.wisestone.owl.web.condition.WorkflowCondition; |
| | | import kr.wisestone.owl.web.form.WorkflowForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface WorkflowService extends AbstractService<Workflow, Long, JpaRepository<Workflow, Long>> { |
| | | |
| | | void addDefaultWorkflow(Workspace workspace, List<ProjectType> projectTypes); |
| | | |
| | | Workflow addWorkflow(WorkflowForm form); |
| | | |
| | | List<WorkflowVo> findWorkflow(Map<String, Object> resJsonData, |
| | | WorkflowCondition condition, Pageable pageable); |
| | | |
| | | void detailWorkflow(Map<String, Object> resJsonData, WorkflowCondition workflowCondition); |
| | | |
| | | Workflow modifyWorkflow(WorkflowForm form); |
| | | |
| | | Workflow getWorkflow(Long id); |
| | | |
| | | void removeWorkflows(WorkflowForm workflowForm); |
| | | |
| | | Workflow findByWorkspaceIdAndProjectType(Long workspaceId, ProjectType projectType); |
| | | |
| | | List<Workflow> findByWorkspaceId(Long workspaceId); |
| | | |
| | | ModelAndView downloadExcel(HttpServletRequest request, Model model); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | |
| | | import kr.wisestone.owl.domain.Project; |
| | | import kr.wisestone.owl.domain.WorkflowStatus; |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import kr.wisestone.owl.vo.WorkflowStatusVo; |
| | | import kr.wisestone.owl.web.condition.WorkflowStatusCondition; |
| | | //import kr.wisestone.owl.web.form.WorkflowStatusForm; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Created by wisestone on 2018-01-03. |
| | | */ |
| | | public interface WorkflowStatusService extends AbstractService<WorkflowStatus, Long, JpaRepository<WorkflowStatus, Long>>{ |
| | | List<WorkflowStatus> addDefaultWorkflowStatus(Project project, ProjectType projectType); |
| | | |
| | | List<WorkflowStatusVo> findWorkflowStatus(Map<String, Object> resJsonData, |
| | | WorkflowStatusCondition condition); |
| | | |
| | | // WorkflowStatus addWorkflowStatus(WorkflowStatusForm workflowStatusForm); |
| | | // |
| | | // WorkflowStatusVo detailWorkflowStatus(Map<String, Object> resJsonData, WorkflowStatusForm workflowStatusForm); |
| | | // |
| | | // WorkflowStatus modifyWorkflowStatus(WorkflowStatusForm workflowStatusForm); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.IssueStatus; |
| | | import kr.wisestone.owl.domain.Workflow; |
| | | import kr.wisestone.owl.domain.WorkflowTransition; |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import kr.wisestone.owl.vo.IssueStatusVo; |
| | | import kr.wisestone.owl.vo.WorkflowTransitionVo; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface WorkflowTransitionService extends AbstractService<WorkflowTransition, Long, JpaRepository<WorkflowTransition, Long>>{ |
| | | |
| | | void addDefaultWorkflowTransition(Workflow workflow, List<IssueStatus> issueStatuses, ProjectType projectType); |
| | | |
| | | List<WorkflowTransition> findByWorkflowId(Long workflowId); |
| | | |
| | | List<WorkflowTransitionVo> findBySourceIssueStatusIdAndWorkflowId(Long sourceIssueStatusId, Long workflowId); |
| | | |
| | | void modify(Workflow workflow, List<IssueStatusVo> issueStatusVos); |
| | | |
| | | WorkflowTransition getWorkflowTransition(Long id); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.web.form.PaymentForm; |
| | | import kr.wisestone.owl.web.form.WorkspaceForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface WorkspaceService extends AbstractService<Workspace, Long, JpaRepository<Workspace, Long>>{ |
| | | Workspace addWorkspace(String workspaceName); |
| | | |
| | | Workspace updateWorkspace(Workspace workspace, PaymentForm paymentForm); |
| | | |
| | | void expireAlarmWorkspace(); |
| | | |
| | | List<Workspace> findSubscribeImmediateExpireDate(); |
| | | |
| | | void initMaxUserAndStorageSize(Workspace workspace); |
| | | |
| | | void cancelWorkspacePayment(Workspace workspace); |
| | | |
| | | Workspace getWorkspace(Long workspaceId); |
| | | |
| | | void find(Map<String, Object> resJsonData); |
| | | |
| | | void out(WorkspaceForm workspaceForm); |
| | | |
| | | void findPrimaryWorkspace(Map<String, Object> resJsonData); |
| | | |
| | | void findMyWorkspace(Map<String, Object> resJsonData); |
| | | |
| | | void removeWorkspace(Workspace workspace, User user); |
| | | |
| | | void modifyWorkspace(WorkspaceForm workspaceForm); |
| | | |
| | | void expireWorkspace(); |
| | | |
| | | void checkUseWorkspace(); |
| | | |
| | | ModelAndView checkUseExcelDownload(Model model); |
| | | |
| | | boolean checkUseTraffic(Long fileSize); |
| | | |
| | | Workspace updateWorkspaceByImmediatePayment(Workspace workspace, int buyUser); |
| | | |
| | | Map<String, Object> getWorkspaceExpireDay(); |
| | | |
| | | Workspace getPrimaryWorkspace(); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.common.MessageAccessor; |
| | | import kr.wisestone.owl.service.AbstractService; |
| | | import kr.wisestone.owl.util.WebAppUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.persistence.EntityManager; |
| | | import javax.persistence.PersistenceContext; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | public abstract class AbstractServiceImpl<T, ID extends Serializable, R extends JpaRepository<T, ID>> |
| | | implements AbstractService<T, ID, R> { |
| | | |
| | | protected abstract JpaRepository<T, ID> getRepository(); |
| | | |
| | | @PersistenceContext |
| | | protected EntityManager entityManager; |
| | | |
| | | @Autowired |
| | | protected MessageAccessor messageAccessor; |
| | | |
| | | @Autowired |
| | | protected WebAppUtil webAppUtil; |
| | | |
| | | private static final int BATCH_COUNT = 200; // 배치 사이즈 |
| | | |
| | | @Override |
| | | public long count() { |
| | | return this.getRepository().count(); |
| | | } |
| | | |
| | | @Override |
| | | public void clear() { |
| | | this.entityManager.clear(); |
| | | } |
| | | |
| | | @Override |
| | | public void detach(Object entity) { |
| | | this.entityManager.detach(entity); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void bulkInsert(List<T> entities) { |
| | | AtomicInteger adGroupInsightIndex = new AtomicInteger(1); |
| | | |
| | | entities.forEach(entity -> { |
| | | entity = this.entityManager.merge(entity); |
| | | |
| | | if (adGroupInsightIndex.get() > 0 && adGroupInsightIndex.get() % BATCH_COUNT == 0) { |
| | | this.entityManager.flush(); |
| | | this.entityManager.clear(); |
| | | } |
| | | adGroupInsightIndex.getAndIncrement(); |
| | | |
| | | }); |
| | | |
| | | entityManager.flush(); |
| | | entityManager.clear(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public T findOne(ID id) { |
| | | Optional<T> entity = this.getRepository().findById(id); |
| | | |
| | | if (entity.isPresent()) { |
| | | return entity.get(); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /*@Override |
| | | @Transactional(readOnly = true) |
| | | public T findOne(ID id) { |
| | | return this.getRepository().getOne(id); |
| | | }*/ |
| | | |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<T> findAll(List<ID> ids) { |
| | | return this.getRepository().findAllById(ids); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | |
| | | import com.amazonaws.services.s3.AmazonS3; |
| | | import com.amazonaws.services.s3.model.*; |
| | | import com.amazonaws.services.s3.transfer.*; |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.AttachedFile; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.domain.enumType.AttachedType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.AttachedFileMapper; |
| | | import kr.wisestone.owl.repository.AttachedFileRepository; |
| | | import kr.wisestone.owl.service.AttachedFileService; |
| | | import kr.wisestone.owl.service.IssueService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.util.WebAppUtil; |
| | | import kr.wisestone.owl.vo.AttachedFileVo; |
| | | import kr.wisestone.owl.vo.ExportExcelAttrVo; |
| | | import kr.wisestone.owl.vo.ExportExcelVo; |
| | | import kr.wisestone.owl.web.condition.AttachedFileCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import kr.wisestone.owl.web.view.FileDownloadView; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.commons.lang3.time.StopWatch; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.messaging.simp.SimpMessagingTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | import java.io.File; |
| | | import java.io.InputStream; |
| | | import java.text.DecimalFormat; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class AttachedFileServiceImpl extends AbstractServiceImpl<AttachedFile, Long, JpaRepository<AttachedFile, Long>> |
| | | implements AttachedFileService { |
| | | |
| | | private static final Logger LOGGER = LoggerFactory.getLogger(AttachedFileServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private AttachedFileRepository attachedFileRepository; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private AttachedFileMapper attachedFileMapper; |
| | | |
| | | @Autowired |
| | | private SimpMessagingTemplate simpMessagingTemplate; |
| | | |
| | | @Value("${use.aws}") |
| | | private boolean bUseAWS; |
| | | |
| | | @Value("${attached.file.path}") |
| | | private String uploadFolder; |
| | | |
| | | @Value("${aws.bucket.name}") |
| | | private String bucketName; |
| | | |
| | | @Value("${aws.s3.url}") |
| | | private String awsS3Url; |
| | | |
| | | @Autowired |
| | | private FileDownloadView fileDownloadView; |
| | | |
| | | @Autowired |
| | | private AmazonS3 amazonS3; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | |
| | | @Override |
| | | protected JpaRepository<AttachedFile, Long> getRepository() { |
| | | return this.attachedFileRepository; |
| | | } |
| | | |
| | | // 첨부 파일을 등록한다. - 이슈 섬머 노트에서 사용 |
| | | @Override |
| | | @Transactional |
| | | public List<AttachedFile> addAttachedFile(List<MultipartFile> multipartFiles, Map<String, Object> content) { |
| | | Long workspaceId = MapUtil.getLong(content, "workspaceId"); |
| | | Long issueId = MapUtil.getLong(content, "issueId"); |
| | | Workspace workspace = this.workspaceService.getWorkspace(workspaceId); |
| | | List<Map<String, Object>> convertFileMaps = Lists.newArrayList(); |
| | | |
| | | for (MultipartFile multipartFile : multipartFiles) { |
| | | convertFileMaps.add(CommonUtil.makeFileMap(multipartFile)); |
| | | } |
| | | |
| | | if (issueId != null) { |
| | | Issue issue = this.issueService.getIssue(issueId); |
| | | return this.addAttachedFiles(workspace, convertFileMaps, issue, null, AttachedType.SUMMER); |
| | | } |
| | | else { |
| | | return this.addAttachedFiles(workspace, convertFileMaps, null, null, AttachedType.TEMP_SUMMER); |
| | | } |
| | | } |
| | | |
| | | // 첨부 파일을 등록한다. - 이슈 생성, 수정에서 사용 |
| | | @Override |
| | | @Transactional |
| | | public void addAttachedFile(List<Map<String, Object>> convertFileMaps, Issue issue, String userAccount) { |
| | | Workspace workspace = issue.getIssueStatus().getWorkspace(); |
| | | |
| | | if (workspace == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_EXIST)); |
| | | } |
| | | |
| | | this.addAttachedFiles(workspace, convertFileMaps, issue, userAccount, AttachedType.ISSUE_ATTACHED); |
| | | } |
| | | |
| | | private List<AttachedFile> addAttachedFiles(Workspace workspace, List<Map<String, Object>> convertFileMaps, Issue issue, String userAccount, AttachedType attachedType) { |
| | | List<AttachedFile> attachedFiles = Lists.newArrayList(); |
| | | AttachedFileCondition attachedFileCondition = new AttachedFileCondition(); |
| | | attachedFileCondition.setWorkspaceId(workspace.getId()); |
| | | |
| | | Long useStorageSize = this.attachedFileMapper.findUseStorage(attachedFileCondition); |
| | | |
| | | if (useStorageSize == null) { |
| | | useStorageSize = 0L; |
| | | } |
| | | |
| | | // 용량 및 파일 확장자 허용 여부 체크 |
| | | this.checkStorageSizeAndFileType(convertFileMaps, workspace.getStorageSize(), useStorageSize); |
| | | |
| | | int totalFileCount = convertFileMaps.size(); // 전체 업로드 파일 개수 |
| | | int uploadFileCount = 1; // 현재 업로드 파일 순서 |
| | | |
| | | for (Map<String, Object> convertFileMap : convertFileMaps) { |
| | | // 파일 업로드 후 awsKey(파일 명)을 가져온다. |
| | | String awsKey = this.uploadFile(convertFileMap, this.uploadFolder + workspace.getId(), userAccount, totalFileCount, uploadFileCount); |
| | | |
| | | attachedFiles.add(new AttachedFile(MapUtil.getString(convertFileMap, "fileName"), MapUtil.getLong(convertFileMap, "fileSize"), MapUtil.getString(convertFileMap, "contentType"), |
| | | this.setMakeFilePath(awsKey, workspace), awsKey, issue, workspace, CommonUtil.getFileType(MapUtil.getString(convertFileMap, "fileName")), attachedType)); |
| | | |
| | | uploadFileCount++; |
| | | } |
| | | |
| | | if (attachedFiles.size() > 0) { |
| | | this.attachedFileRepository.saveAll(attachedFiles); |
| | | } |
| | | |
| | | return attachedFiles; |
| | | } |
| | | |
| | | // 용량 및 파일 확장자 허용 여부 체크 |
| | | private void checkStorageSizeAndFileType(List<Map<String, Object>> convertFileMaps, Long totalStorageSize, Long useStorageSize) { |
| | | for (Map<String, Object> convertFileMap : convertFileMaps) { |
| | | Long fileSize = MapUtil.getLong(convertFileMap, "fileSize"); |
| | | String fileName = MapUtil.getString(convertFileMap, "fileName"); |
| | | |
| | | if (fileSize == null) { |
| | | fileSize = 0L; |
| | | } |
| | | |
| | | // 용량 초과 체크 |
| | | if (totalStorageSize < (useStorageSize + fileSize)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.WORKSPACE_STORAGE_SIZE_EXCESS)); |
| | | } |
| | | |
| | | // 파일 확장자 체크 |
| | | if (!CommonUtil.checkFileType(fileName)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.FILE_TYPE_NOT_ALLOW)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈 생성, 수정에서 섬머 노트로 업로드한 이미지와 이슈를 연결시킨다. |
| | | @Override |
| | | @Transactional |
| | | public void connectIssueIdAttachedFile(Issue issue, IssueForm issueForm) { |
| | | for (Long attachedFileId : issueForm.getAttachedFileIds()) { |
| | | AttachedFile attachedFile = this.getAttachedFile(attachedFileId); |
| | | attachedFile.setIssue(issue); |
| | | attachedFile.setAttachedType(AttachedType.SUMMER); |
| | | this.attachedFileRepository.save(attachedFile); |
| | | } |
| | | |
| | | this.attachedFileRepository.flush(); |
| | | } |
| | | |
| | | // 이슈 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<AttachedFileVo> findAttachedFile(Map<String, Object> resJsonData, AttachedFileCondition condition) { |
| | | List<AttachedFileVo> attachedFileVos = Lists.newArrayList(); |
| | | |
| | | for (AttachedFile attachedFile : this.findByIssueId(condition.getIssueId())) { |
| | | AttachedFileVo attachedFileVo = ConvertUtil.copyProperties(attachedFile, AttachedFileVo.class, "fileType"); |
| | | attachedFileVo.setFileType(attachedFile.getFileType().toString()); |
| | | attachedFileVos.add(attachedFileVo); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, attachedFileVos); |
| | | |
| | | return attachedFileVos; |
| | | } |
| | | |
| | | // 이슈 아이디로 첨부 파일을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<AttachedFile> findByIssueId(Long issueId) { |
| | | return this.attachedFileRepository.findByIssueId(issueId); |
| | | } |
| | | |
| | | // 첨부 파일 아이디로 첨부 파일을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public AttachedFile getAttachedFile(Long attachedFileId) { |
| | | AttachedFile attachedFile = this.findOne(attachedFileId); |
| | | |
| | | if (attachedFile == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ATTACHED_FILE_NOT_EXIST)); |
| | | } |
| | | |
| | | return attachedFile; |
| | | } |
| | | |
| | | // 첨부파일 삭제 |
| | | @Override |
| | | @Transactional |
| | | public void removeAttachedFiles(List<Long> removeIds) { |
| | | for (Long attachedId : removeIds) { |
| | | AttachedFile attachedFile = this.getAttachedFile(attachedId); |
| | | |
| | | switch (attachedFile.getAttachedType()) { |
| | | case SUMMER: |
| | | // 이슈와 첨부 파일 연결을 해제한다. |
| | | attachedFile.setIssue(null); |
| | | break; |
| | | case ISSUE_ATTACHED: |
| | | // 첨부 파일을 삭제한다. |
| | | this.removeAttachedFiles(attachedFile); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 첨부 파일을 삭제한다. |
| | | private void removeAttachedFiles(AttachedFile attachedFile) { |
| | | // 파일을 삭제한다. |
| | | this.removeFile(attachedFile.getAwsKey(), attachedFile.getWorkspace().getId()); |
| | | |
| | | this.attachedFileRepository.delete(attachedFile); |
| | | } |
| | | |
| | | // 업무 공간 삭제시 이슈에 첨부된 파일을 시스템에서 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void deleteWorkspaceCascadeAttachedFile(Workspace workspace) { |
| | | List<Map<String, Object>> attachedFiles = this.attachedFileMapper.findByWorkspaceId(workspace.getId()); |
| | | |
| | | for (Map<String, Object> attachedFile : attachedFiles) { |
| | | // 파일을 삭제한다. |
| | | this.removeFile(MapUtil.getString(attachedFile, "awsKey"), MapUtil.getLong(attachedFile, "workspaceId")); |
| | | } |
| | | |
| | | // 첨부 파일 삭제 |
| | | this.attachedFileMapper.deleteAttachedFileByWorkspaceId(workspace.getId()); |
| | | } |
| | | |
| | | // 프로젝트 삭제시 이슈에 첨부된 파일을 시스템에서 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void deleteIssueCascadeAttachedFile(List<Long> issueIds, Workspace workspace) { |
| | | // 이슈가 없을 경우에는 아래 로직을 타지 않는다. -> 모든 업무공간에 첨부파일이 삭제될 위험이 있음. |
| | | if (issueIds.size() < 1) { |
| | | return; |
| | | } |
| | | |
| | | AttachedFileCondition attachedFileCondition = new AttachedFileCondition(); |
| | | attachedFileCondition.setIssueIds(issueIds); |
| | | attachedFileCondition.setWorkspaceId(workspace.getId()); |
| | | |
| | | List<Map<String, Object>> attachedFiles = this.attachedFileMapper.findByIssueIds(attachedFileCondition); |
| | | |
| | | for (Map<String, Object> attachedFile : attachedFiles) { |
| | | // 파일을 삭제한다. |
| | | this.removeFile(MapUtil.getString(attachedFile, "awsKey"), MapUtil.getLong(attachedFile, "workspaceId")); |
| | | } |
| | | |
| | | // 첨부 파일 삭제 |
| | | this.attachedFileMapper.deleteAttachedFileByIssueIds(attachedFileCondition); |
| | | } |
| | | |
| | | |
| | | // 업무 공간에서 사용중인 저장 용량을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Long findUseStorage(Workspace workspace) { |
| | | AttachedFileCondition attachedFileCondition = new AttachedFileCondition(); |
| | | attachedFileCondition.setWorkspaceId(workspace.getId()); |
| | | return this.attachedFileMapper.findUseStorage(attachedFileCondition); |
| | | } |
| | | |
| | | // 업무 공간에서 사용 트래픽을 체크하고 트래픽 초과시 다운로드를 막는다. |
| | | @Override |
| | | @Transactional |
| | | public ModelAndView checkUseWorkspaceTraffic(Long id, Model model) { |
| | | AttachedFile attachedFile = this.getAttachedFile(id); |
| | | // 트래픽 사용량을 저장하고 초과할 경우에는 해당 업무 공간에서 다운로드를 일시적으로 금지한다. |
| | | if (!this.workspaceService.checkUseTraffic(attachedFile.getSize())) { |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.setFileName("해당 업무 공간에서 사용할 수 있는 트래픽이 초과되었습니다. 트래픽을 추가하려면 와이즈스톤 담당자에게 문의하세요. - supportowl@wisestone.kr"); |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("name", "", 120, ExportExcelAttrVo.ALIGN_LEFT)); |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | ModelAndView objModelView = null; |
| | | |
| | | if( this.bUseAWS ) |
| | | { |
| | | objModelView = downloadFileFromAWS(id, model); |
| | | } |
| | | else |
| | | { |
| | | objModelView = downloadFileFromLocal(id, model); |
| | | } |
| | | |
| | | return objModelView; |
| | | } |
| | | |
| | | private ModelAndView downloadFileFromLocal(Long id, Model model) { |
| | | AttachedFile attachedFile = this.getAttachedFile(id); |
| | | |
| | | InputStream objectInputStream = CommonUtil.getFileInputStream(this.bucketName + this.uploadFolder + attachedFile.getWorkspace().getId(), attachedFile.getAwsKey()); |
| | | |
| | | try { |
| | | byte[] bytes = IOUtils.toByteArray(objectInputStream); |
| | | AttachedFileVo attachedFileVo = ConvertUtil.copyProperties(attachedFile, AttachedFileVo.class); |
| | | attachedFileVo.setBytes(bytes); |
| | | model.addAttribute("fileDownloadTarget", attachedFileVo); |
| | | } catch (Exception e) { |
| | | LOGGER.error("첨부 파일 다운로드에 실패하였습니다."); |
| | | } |
| | | |
| | | return new ModelAndView(this.fileDownloadView); |
| | | } |
| | | |
| | | private ModelAndView downloadFileFromAWS(Long id, Model model) { |
| | | AttachedFile attachedFile = this.getAttachedFile(id); |
| | | |
| | | GetObjectRequest getObjectRequest = new GetObjectRequest(this.bucketName + this.uploadFolder + attachedFile.getWorkspace().getId(), attachedFile.getAwsKey()); |
| | | S3Object s3Object = this.amazonS3.getObject(getObjectRequest); |
| | | S3ObjectInputStream objectInputStream = s3Object.getObjectContent(); |
| | | |
| | | try { |
| | | byte[] bytes = IOUtils.toByteArray(objectInputStream); |
| | | AttachedFileVo attachedFileVo = ConvertUtil.copyProperties(attachedFile, AttachedFileVo.class); |
| | | attachedFileVo.setBytes(bytes); |
| | | model.addAttribute("fileDownloadTarget", attachedFileVo); |
| | | } catch (Exception e) { |
| | | LOGGER.error("아마존 클라우드에서 첨부 파일 다운로드에 실패하였습니다."); |
| | | } |
| | | |
| | | return new ModelAndView(this.fileDownloadView); |
| | | } |
| | | |
| | | // 이슈와 연결되지 않은 첨부파일 삭제 |
| | | @Override |
| | | @Transactional |
| | | public void deleteAttachedFileNotId() { |
| | | this.attachedFileMapper.deleteAttachedFileNotId(); |
| | | } |
| | | |
| | | // 파일을 업로드 한다. |
| | | @Override |
| | | @Transactional |
| | | public String uploadFile(Map<String, Object> convertFileMap, String awsUploadFolder, String userAccount, int totalFileCount, int uploadFileCount) { |
| | | String strKeyName = ""; |
| | | |
| | | if( this.bUseAWS ) |
| | | { |
| | | strKeyName = uploadFileToAws(convertFileMap, awsUploadFolder, userAccount, totalFileCount, uploadFileCount); |
| | | } |
| | | else |
| | | { |
| | | strKeyName = uploadFileToLocal(convertFileMap, awsUploadFolder, userAccount, totalFileCount, uploadFileCount); |
| | | } |
| | | |
| | | return strKeyName; |
| | | } |
| | | |
| | | // local storage로 이동한다. |
| | | private String uploadFileToLocal(Map<String, Object> convertFileMap, String awsUploadFolder, String userAccount, int totalFileCount, int uploadFileCount) { |
| | | String awsKeyName = CommonUtil.getFileNameByUUID(MapUtil.getString(convertFileMap, "fileName")); |
| | | StopWatch serviceStart = new StopWatch(); |
| | | serviceStart.start(); |
| | | File file = (File) convertFileMap.get("file"); |
| | | |
| | | try { |
| | | // 이슈 생성, 수정에서 파일을 업로드할때는 비동기로 올리며 업로드 진행률을 표시해준다. |
| | | if (!StringUtils.isEmpty(userAccount)) { |
| | | } |
| | | |
| | | CommonUtil.moveToSaveStorage(this.bucketName + awsUploadFolder, awsKeyName, file); |
| | | |
| | | if (file.exists()) { |
| | | file.delete(); |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("파일 업로드 에러 :" + e.getMessage()); |
| | | } |
| | | |
| | | serviceStart.stop(); |
| | | |
| | | return awsKeyName; |
| | | } |
| | | |
| | | // 아마존 클라우드에 파일을 업로드한다. |
| | | private String uploadFileToAws(Map<String, Object> convertFileMap, String awsUploadFolder, String userAccount, int totalFileCount, int uploadFileCount) { |
| | | String awsKeyName = CommonUtil.getFileNameByUUID(MapUtil.getString(convertFileMap, "fileName")); |
| | | StopWatch serviceStart = new StopWatch(); |
| | | serviceStart.start(); |
| | | File file = (File) convertFileMap.get("file"); |
| | | |
| | | TransferManager transferManager = TransferManagerBuilder |
| | | .standard() |
| | | .withS3Client(this.amazonS3) |
| | | /*.withMultipartUploadThreshold((long) 5*1024*1024)*/ |
| | | /*.withExecutorFactory(() -> Executors.newFixedThreadPool(20))*/ |
| | | .build(); |
| | | |
| | | /*TransferManager transferManager = TransferManagerBuilder |
| | | .standard() |
| | | .withS3Client(this.amazonS3) |
| | | .withDisableParallelDownloads(false) |
| | | .withMinimumUploadPartSize((long)(5 * MB)) |
| | | .withMultipartUploadThreshold((long)(16 * MB)) |
| | | .withMultipartCopyPartSize((long)(5 * MB)) |
| | | .withMultipartCopyThreshold((long)(100 * MB)) |
| | | .withExecutorFactory(() -> Executors.newFixedThreadPool(20)) |
| | | .build();*/ |
| | | |
| | | try { |
| | | PutObjectRequest putObjectRequest = |
| | | new PutObjectRequest(this.bucketName + awsUploadFolder, awsKeyName, file); |
| | | putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead); // file permission |
| | | //this.amazonS3.putObject(putObjectRequest); // upload file |
| | | |
| | | long fileSize = MapUtil.getLong(convertFileMap, "fileSize"); |
| | | String fileName = MapUtil.getString(convertFileMap, "fileName"); |
| | | |
| | | // 이슈 생성, 수정에서 파일을 업로드할때는 비동기로 올리며 업로드 진행률을 표시해준다. |
| | | if (!StringUtils.isEmpty(userAccount)) { |
| | | com.amazonaws.event.ProgressListener progressListener = new com.amazonaws.event.ProgressListener() { |
| | | long bytesUploaded = 0; |
| | | |
| | | SimpMessagingTemplate webSocket = simpMessagingTemplate; |
| | | |
| | | @Override |
| | | public void progressChanged(com.amazonaws.event.ProgressEvent progressEvent) { |
| | | this.bytesUploaded += progressEvent.getBytesTransferred();// add counter |
| | | double uploadProcess = this.bytesUploaded * 100.0 / fileSize; |
| | | String percent = new DecimalFormat("###").format(uploadProcess); |
| | | Map<String, Object> fileMap = new HashMap<>(); |
| | | fileMap.put("display", (uploadProcess < 100)); |
| | | fileMap.put("serverFileName", fileName); |
| | | fileMap.put("serverProgress", percent + "%"); |
| | | fileMap.put("totalFileCount", totalFileCount); |
| | | fileMap.put("uploadFileCount", uploadFileCount); |
| | | |
| | | this.webSocket.convertAndSendToUser(userAccount, "/notification/file-upload-process", fileMap); |
| | | } |
| | | }; |
| | | |
| | | putObjectRequest.setGeneralProgressListener(progressListener); |
| | | } |
| | | |
| | | Upload upload = transferManager.upload(putObjectRequest); |
| | | upload.waitForCompletion(); |
| | | transferManager.shutdownNow(false); |
| | | |
| | | if (file.exists()) { |
| | | file.delete(); |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("파일 업로드 에러 :" + e.getMessage()); |
| | | } |
| | | |
| | | serviceStart.stop(); |
| | | |
| | | return awsKeyName; |
| | | } |
| | | |
| | | // 파일을 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeFile(String key, Long workspaceId) { |
| | | try { |
| | | if( this.bUseAWS ) |
| | | { |
| | | removeFileToAws(key, workspaceId); |
| | | } |
| | | else |
| | | { |
| | | removeFileToLocal(key, workspaceId); |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("파일 삭제 에러 :" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // 파일을 삭제한다. |
| | | private void removeFileToLocal(String key, Long workspaceId) { |
| | | try { |
| | | if(workspaceId > 0 ) |
| | | { |
| | | CommonUtil.deleteToSaveStorage(this.bucketName + this.uploadFolder, key); |
| | | } |
| | | else |
| | | { |
| | | CommonUtil.deleteToSaveStorage(this.bucketName + this.uploadFolder + workspaceId, key); |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("파일 삭제 에러 :" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // 아마존클라우드에서 파일을 삭제한다. |
| | | private void removeFileToAws(String key, Long workspaceId) { |
| | | try { |
| | | if(workspaceId > 0 ) |
| | | { |
| | | this.amazonS3.deleteObject(this.bucketName + this.uploadFolder, key); |
| | | } |
| | | else |
| | | { |
| | | this.amazonS3.deleteObject(this.bucketName + this.uploadFolder + workspaceId, key); |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("파일 삭제 에러 :" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // 업로드되는 전체 경로를 가져온다. |
| | | private String setMakeFilePath(String path, Workspace workspace) { |
| | | String strFilePath = ""; |
| | | |
| | | if( this.bUseAWS ) |
| | | { |
| | | strFilePath = setMakeAwsFilePath(path, workspace); |
| | | } |
| | | else |
| | | { |
| | | strFilePath = setMakeLocalFilePath(path, workspace); |
| | | } |
| | | |
| | | return strFilePath; |
| | | } |
| | | |
| | | // 업로드되는 전체 경로를 가져온다. |
| | | private String setMakeLocalFilePath(String path, Workspace workspace) { |
| | | return this.awsS3Url + this.bucketName + this.uploadFolder + workspace.getId() + "/" + path; |
| | | } |
| | | |
| | | // 아마존 클라우드에 업로드되는 전체 경로를 가져온다. |
| | | private String setMakeAwsFilePath(String path, Workspace workspace) { |
| | | return this.awsS3Url + this.bucketName + this.uploadFolder + workspace.getId() + "/" + path; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.common.ExcelConditionCheck; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.CustomField; |
| | | import kr.wisestone.owl.domain.IssueCustomFieldValue; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.CustomFieldMapper; |
| | | import kr.wisestone.owl.repository.CustomFieldRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.condition.CustomFieldCondition; |
| | | import kr.wisestone.owl.web.form.CustomFieldForm; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class CustomFieldServiceImpl extends AbstractServiceImpl<CustomField, Long, JpaRepository<CustomField, Long>> implements CustomFieldService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(CustomFieldServiceImpl.class); |
| | | |
| | | public enum UseType { |
| | | Y, |
| | | N, |
| | | } |
| | | |
| | | @Autowired |
| | | private CustomFieldRepository customFieldRepository; |
| | | |
| | | @Autowired |
| | | private CustomFieldMapper customFieldMapper; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private CustomFieldValueService customFieldValueService; |
| | | |
| | | @Autowired |
| | | private IssueCustomFieldValueService issueCustomFieldValueService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | @Autowired |
| | | private ExcelConditionCheck excelConditionCheck; |
| | | |
| | | @Override |
| | | protected JpaRepository<CustomField, Long> getRepository() { |
| | | return this.customFieldRepository; |
| | | } |
| | | |
| | | // 사용자 정의 필드를 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public CustomField addCustomField(CustomFieldForm customFieldForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 이름 유효성 체크 |
| | | this.verifyName(customFieldForm.getName(), null); |
| | | // 옵션 값 유효 체크 |
| | | this.verifyOptions(customFieldForm); |
| | | |
| | | CustomField customField = ConvertUtil.copyProperties(customFieldForm, CustomField.class, "customFieldType"); |
| | | customField.setUse("Y"); |
| | | Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | customField.setWorkspace(workspace); |
| | | customField.setCustomFieldType(CustomFieldType.valueOf(customFieldForm.getCustomFieldType())); // 사용자 정의 필드 유형을 셋팅한다. |
| | | |
| | | this.customFieldRepository.saveAndFlush(customField); |
| | | |
| | | this.customFieldValueService.addCustomFieldValues(customField, customFieldForm.getOptions(), null); // 사용자 정의 필드 값 추가 |
| | | |
| | | return customField; |
| | | } |
| | | |
| | | // 이름 유효성 체크 |
| | | private void verifyName(String name, Long id) { |
| | | if (StringUtils.isEmpty(name)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_NOT_NAME)); |
| | | } |
| | | |
| | | if (name.length() > 15) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_NAME_MAX_LENGTH_OUT)); |
| | | } |
| | | |
| | | CustomField customField; |
| | | Long workspaceId = this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId(); |
| | | |
| | | if (id == null) { |
| | | customField = this.customFieldRepository.findByNameAndWorkspaceId(name, workspaceId); |
| | | } |
| | | else { |
| | | customField = this.customFieldRepository.findByNameAndWorkspaceIdAndIdNot(name, workspaceId, id); |
| | | } |
| | | |
| | | if (customField != null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_USED_NAME)); |
| | | } |
| | | } |
| | | |
| | | // 옵션 값 유효 체크 |
| | | private void verifyOptions(CustomFieldForm customFieldForm) { |
| | | // 사용자 정의 필드 유형이 텍스트 일때는 옵션 값이 존재하면 안된다. |
| | | if (CustomFieldType.valueOf(customFieldForm.getCustomFieldType()).equals(CustomFieldType.INPUT)) { |
| | | if (customFieldForm.getOptions().size() > 0) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_OPTIONS_NOT_USE_INPUT_FIELD)); |
| | | } |
| | | |
| | | if(customFieldForm.getDefaultValue().length() > 100) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_DEFAULT_VALUE_MAX_LENGTH_OUT)); |
| | | } |
| | | } |
| | | |
| | | if (customFieldForm.getOptions().size() > 0) { |
| | | // 사용자 정의 필드 옵션 값이 null 이거나 공백인 경우를 찾는다. |
| | | for (String option : customFieldForm.getOptions()) { |
| | | if (StringUtils.isEmpty(option)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_OPTIONS_NOT_EMPTY_VALUE)); |
| | | } |
| | | // 옵션 값 최대 길이 체크 |
| | | if (option.length() > 15) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_OPTION_VALUE_MAX_LENGTH_OUT)); |
| | | } |
| | | } |
| | | |
| | | // 사용자 정의 필드 기본 값이 옵션에 존재하지 않을 경우를 찾는다. |
| | | if (!StringUtils.isEmpty(customFieldForm.getDefaultValue())) { |
| | | switch (CustomFieldType.valueOf(customFieldForm.getCustomFieldType())) { |
| | | case SINGLE_SELECT: |
| | | if (customFieldForm.getDefaultValue().split("#").length > 2) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_OPTIONS_NOT_USE_MULTI_DEFAULT_VALUE)); |
| | | } |
| | | // 기본 값으로 지정한 값이 옵션에 있는지 확인한다. |
| | | this.verifyOptionsDefaultValue(customFieldForm); |
| | | |
| | | break; |
| | | case MULTI_SELECT: |
| | | // 기본 값으로 지정한 값이 옵션에 있는지 확인한다. |
| | | this.verifyOptionsDefaultValue(customFieldForm); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 기본 값으로 지정한 값이 옵션에 있는지 확인한다. |
| | | private void verifyOptionsDefaultValue(CustomFieldForm customFieldForm) { |
| | | // 중복된 옵션 값 찾기 |
| | | Map<String, Object> optionValueDictionary = new HashMap<>(); |
| | | |
| | | for (String defaultValue : customFieldForm.getDefaultValue().split("#")) { |
| | | if (!StringUtils.isEmpty(defaultValue)) { |
| | | if (!customFieldForm.getOptions().contains(defaultValue)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_OPTIONS_NOT_EXIST_DEFAULT_VALUE)); |
| | | } |
| | | |
| | | if (MapUtil.getBoolean(optionValueDictionary, defaultValue) == null) { |
| | | optionValueDictionary.put(defaultValue, true); |
| | | } |
| | | else { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_OPTIONS_USED_EXIST_DEFAULT_VALUE)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 사용자 정의 필드 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<CustomFieldVo> findCustomField(Map<String, Object> resJsonData, |
| | | CustomFieldCondition condition, Pageable pageable) { |
| | | |
| | | condition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | condition.setPageSize(pageable.getPageSize()); |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | List<Map<String, Object>> results = this.customFieldMapper.find(condition); |
| | | Long totalCount = this.customFieldMapper.count(condition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | // 사용자 정의 필드 조회 결과를 CustomFieldVo 로 변환한다. |
| | | List<CustomFieldVo> customFieldVos = this.makeCustomFieldVos(results); |
| | | |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, customFieldVos); |
| | | |
| | | return customFieldVos; |
| | | } |
| | | |
| | | // 사용자 정의 필드 조회 결과를 CustomFieldVo 로 변환한다. |
| | | private List<CustomFieldVo> makeCustomFieldVos(List<Map<String, Object>> results) { |
| | | List<CustomFieldVo> customFieldVos = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | CustomFieldVo customFieldVo = ConvertUtil.convertMapToClass(result, CustomFieldVo.class); |
| | | CustomField customField = this.getCustomField(customFieldVo.getId()); |
| | | customFieldVo.setCustomFieldValueVos(ConvertUtil.convertObjectsToClasses(customField.getCustomFieldValues(), CustomFieldValueVo.class)); |
| | | customFieldVos.add(customFieldVo); |
| | | } |
| | | |
| | | return customFieldVos; |
| | | } |
| | | |
| | | |
| | | // 사용자 정의 필드 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailCustomField(Map<String, Object> resJsonData, CustomFieldCondition customFieldCondition) { |
| | | CustomFieldVo customFieldVo = new CustomFieldVo(); |
| | | |
| | | if (customFieldCondition.getId() != null) { |
| | | CustomField customField = this.getCustomField(customFieldCondition.getId()); |
| | | customFieldVo = ConvertUtil.copyProperties(customField, CustomFieldVo.class); |
| | | customFieldVo.setCustomFieldType(customField.getCustomFieldType().toString()); |
| | | |
| | | switch (customFieldCondition.getDeep()) { |
| | | case "01": // 사용자 정의 필드 옵션 값을 가져온다. |
| | | customFieldVo.setCustomFieldValueVos(ConvertUtil.convertObjectsToClasses(customField.getCustomFieldValues(), CustomFieldValueVo.class)); |
| | | // 사용자 정의 필드 옵션 값이 이슈에서 사용되고 있는지 확인한 후 플래그 값을 설정한다. |
| | | List<IssueCustomFieldValue> issueCustomFieldValues = this.issueCustomFieldValueService.findByCustomFieldId(customField); |
| | | if (issueCustomFieldValues.size() > 0) { |
| | | customFieldVo.setUseCustomFieldValue(true); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, customFieldVo); |
| | | } |
| | | |
| | | // 사용자 정의 필드를 수정한다. |
| | | @Override |
| | | @Transactional |
| | | public CustomField modifyCustomField(CustomFieldForm customFieldForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | CustomField customField = this.getCustomField(customFieldForm.getId()); |
| | | CustomFieldType oldCustomFieldType = customField.getCustomFieldType(); |
| | | // 이름 유효성 체크 |
| | | this.verifyName(customFieldForm.getName(), customFieldForm.getId()); |
| | | // 옵션 값 유효 체크 |
| | | this.verifyOptions(customFieldForm); |
| | | // 사용자 정의 필드 유형이 단일, 다중 선택에서 문자열로 변경될 경우 사용자 정의 필드 값을 초기화한다. |
| | | this.checkChangeCustomFieldType(customFieldForm, customField); |
| | | |
| | | ConvertUtil.copyProperties(customFieldForm, customField, "id", "customFieldType"); |
| | | customField.setCustomFieldType(CustomFieldType.valueOf(customFieldForm.getCustomFieldType())); |
| | | |
| | | this.customFieldRepository.saveAndFlush(customField); |
| | | this.customFieldValueService.addCustomFieldValues(customField, customFieldForm.getOptions(), oldCustomFieldType); // 사용자 정의 필드 옵션 값 추가 |
| | | |
| | | return customField; |
| | | } |
| | | |
| | | // 사용자 정의 필드 유형이 단일, 다중 선택에서 문자열로 변경될 경우 사용자 정의 필드 값을 초기화한다. |
| | | private void checkChangeCustomFieldType(CustomFieldForm customFieldForm, CustomField customField) { |
| | | if (!customField.getCustomFieldType().equals(CustomFieldType.INPUT)) { |
| | | // 단일, 다중 선택에서 문자열 필드로 변경된 경우 |
| | | if (CustomFieldType.valueOf(customFieldForm.getCustomFieldType()).equals(CustomFieldType.INPUT)) { |
| | | customField.getCustomFieldValues().clear(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public CustomField getCustomField(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_NOT_EXIST)); |
| | | } |
| | | |
| | | |
| | | CustomField customField = this.findOne(id); |
| | | |
| | | if (customField == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_NOT_EXIST)); |
| | | } |
| | | |
| | | return customField; |
| | | } |
| | | |
| | | // 사용자 정의 필드를 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeCustomFields(CustomFieldForm customFieldForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | if (customFieldForm.getRemoveIds().size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_REMOVE_NOT_SELECT)); |
| | | } |
| | | |
| | | for (Long projectId : customFieldForm.getRemoveIds()) { |
| | | this.removeCustomFields(projectId); |
| | | } |
| | | |
| | | // this.customFieldRepository.flush(); |
| | | } |
| | | |
| | | private void removeCustomFields(Long customFieldId) { |
| | | CustomField customField = this.getCustomField(customFieldId); |
| | | customField.setUse(UseType.N.toString()); |
| | | this.customFieldRepository.saveAndFlush(customField); |
| | | // this.customFieldRepository.delete(customField); |
| | | } |
| | | |
| | | // 이슈 엑셀 import 에서 사용한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public CustomField findByName(String name) { |
| | | return this.customFieldRepository.findByNameAndWorkspaceId(name, this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | |
| | | // 사용자 정의 필드 목록을 엑셀로 다운로드 한다. |
| | | @Override |
| | | @Transactional |
| | | public ModelAndView downloadExcel(HttpServletRequest request, Model model) { |
| | | // 사용 공간에서 로그인한 사용자가 비활성인지 확인하고 비활성일 경우 엑셀 다운로드를 금지한다. |
| | | ModelAndView modelAndView = this.workspaceService.checkUseExcelDownload(model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | Map<String, Object> conditions = new HashMap<>(); |
| | | // 엑셀 다운로드에 필요한 검색 조건 정보를 추출하고 검색 조건 추출에 오류가 발생하면 경고를 표시해준다. |
| | | modelAndView = this.excelConditionCheck.checkCondition(conditions, request, model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | CustomFieldCondition customFieldCondition = CustomFieldCondition.make(conditions); |
| | | customFieldCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | List<Map<String, Object>> results = this.customFieldMapper.find(customFieldCondition); |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | String customFieldType = MapUtil.getString(result, "customFieldType"); |
| | | String customFieldTypeName = ""; |
| | | |
| | | if (customFieldType != null) { |
| | | switch(customFieldType) { |
| | | case "INPUT" : |
| | | customFieldTypeName = this.messageAccessor.message("common.stringField"); // 문자열 필드 |
| | | break; |
| | | case "SINGLE_SELECT" : |
| | | customFieldTypeName = this.messageAccessor.message("common.singleSelectionField"); // 단일 선택 필드 |
| | | break; |
| | | case "MULTI_SELECT" : |
| | | customFieldTypeName = this.messageAccessor.message("common.multipleSelectionField"); // 다중 선택 필드 |
| | | break; |
| | | } |
| | | } |
| | | |
| | | result.put("customFieldTypeName", customFieldTypeName); |
| | | } |
| | | |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.setFileName(this.messageAccessor.message("common.customFieldList")); // 사용자 정의 필드 목록 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("name", this.messageAccessor.message("common.customField"), 15, ExportExcelAttrVo.ALIGN_LEFT)); // 사용자 정의 필드 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("customFieldTypeName", this.messageAccessor.message("common.fieldType"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 필드 유형 |
| | | // 엑셀에 넣을 데이터 |
| | | excelInfo.setDatas(results); |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | // 업무 공간에 있는 모든 사용자 정의 필드을 조회한다. 이슈 엑셀 import 에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<CustomField> findByWorkspaceId() { |
| | | return this.customFieldRepository.findByWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.CustomField; |
| | | import kr.wisestone.owl.domain.CustomFieldValue; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.CustomFieldValueRepository; |
| | | import kr.wisestone.owl.service.CustomFieldValueService; |
| | | import kr.wisestone.owl.service.IssueCustomFieldValueService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class CustomFieldValueServiceImpl extends AbstractServiceImpl<CustomFieldValue, Long, JpaRepository<CustomFieldValue, Long>> implements CustomFieldValueService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(CustomFieldValueServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private CustomFieldValueRepository customFieldValueRepository; |
| | | |
| | | @Autowired |
| | | private IssueCustomFieldValueService issueCustomFieldValueService; |
| | | |
| | | @Override |
| | | protected JpaRepository<CustomFieldValue, Long> getRepository() { |
| | | return this.customFieldValueRepository; |
| | | } |
| | | |
| | | // 사용자 정의 필드 값을 추가한다. |
| | | @Override |
| | | @Transactional |
| | | public void addCustomFieldValues(CustomField customField, List<String> values, CustomFieldType oldCustomFieldType) { |
| | | if (oldCustomFieldType != null) { |
| | | // 텍스트 입력 필드일 때는 이슈에서 사용되고 있는 사용자 정의 필드 값 확인 후 삭제 처리 |
| | | if (customField.getCustomFieldType().equals(CustomFieldType.INPUT)) { |
| | | // 이전에도 텍스트 필드였다면 사용자 정의 필드 값을 삭제하지 않는다. |
| | | if (CustomFieldType.INPUT.equals(oldCustomFieldType)) { |
| | | return; |
| | | } |
| | | // 사용자 정의 필드 옵션 값이 변경되었을 때 사용자 정의 필드 값을 사용하는 이슈에서 해당 값이 존재하는지 확인하고 없어졌으면 삭제해준다. |
| | | this.issueCustomFieldValueService.checkExistIssueCustomFieldValue(customField, values, oldCustomFieldType); |
| | | return; |
| | | } |
| | | |
| | | // 다중선택 필드에서 단일 선택 필드로 변경할 경우 모든 값을 삭제처리한다. |
| | | if (oldCustomFieldType.equals(CustomFieldType.MULTI_SELECT) && customField.getCustomFieldType().equals(CustomFieldType.SINGLE_SELECT)) { |
| | | // 이슈에서 저장된 해당 사용자 정의 필드 값을 모두 삭제한다. |
| | | this.issueCustomFieldValueService.removeIssueCustomFieldValuesByCustomFieldId(customField); |
| | | } |
| | | } |
| | | else { |
| | | // 텍스트 입력 필드일 때는 바로 종료 |
| | | if (customField.getCustomFieldType().equals(CustomFieldType.INPUT)) { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 사용자 정의 필드 값이 0개 일 경우에는 바로 종료 |
| | | if (values.size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_OPTIONS_NOT_VALUE)); |
| | | } |
| | | |
| | | List<CustomFieldValue> customFieldValues = Lists.newArrayList(); |
| | | List<String> addValues = Lists.newArrayList(); |
| | | List<CustomFieldValue> removeValues = Lists.newArrayList(); |
| | | |
| | | |
| | | // 삭제해야할 대상을 추출한다. |
| | | for (CustomFieldValue customFieldValue : customField.getCustomFieldValues()) { |
| | | Boolean exist = false; |
| | | |
| | | for (String value : values) { |
| | | if (value.equals(customFieldValue.getValue())) { |
| | | exist = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 새로 올라온 값에 기존 값이 없으면 삭제대상 |
| | | if (!exist) { |
| | | removeValues.add(customFieldValue); |
| | | } |
| | | } |
| | | |
| | | // 추가해야할 값을 추출한다. |
| | | for (String value : values) { |
| | | Boolean exist = false; |
| | | |
| | | for (CustomFieldValue customFieldValue : customField.getCustomFieldValues()) { |
| | | if (customFieldValue.getValue().equals(value)) { |
| | | exist = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 새로 올라온 값이 기존에 없다면 추가 값 |
| | | if (!exist) { |
| | | addValues.add(value); |
| | | } |
| | | } |
| | | |
| | | // 삭제 대상 삭제 |
| | | if (removeValues.size() > 0) { |
| | | this.customFieldValueRepository.deleteInBatch(removeValues); |
| | | } |
| | | |
| | | // 추가 대상 저장 |
| | | for (String value : addValues) { |
| | | CustomFieldValue customFieldValue = new CustomFieldValue(customField, value); |
| | | customFieldValues.add(customFieldValue); |
| | | } |
| | | |
| | | this.customFieldValueRepository.saveAll(customFieldValues); |
| | | // 사용자 정의 필드 옵션 값이 변경되었을 때 사용자 정의 필드 값을 사용하는 이슈에서 해당 값이 존재하는지 확인하고 없어졌으면 삭제해준다. |
| | | this.issueCustomFieldValueService.checkExistIssueCustomFieldValue(customField, values, oldCustomFieldType); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.Event; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.EventMapper; |
| | | import kr.wisestone.owl.repository.EventRepository; |
| | | import kr.wisestone.owl.service.EventService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.EventVo; |
| | | import kr.wisestone.owl.vo.ResPage; |
| | | import kr.wisestone.owl.web.condition.EventCondition; |
| | | import kr.wisestone.owl.web.form.EventForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class EventServiceImpl extends AbstractServiceImpl<Event, Long, JpaRepository<Event, Long>> implements EventService { |
| | | |
| | | @Autowired |
| | | private EventRepository eventRepository; |
| | | |
| | | @Autowired |
| | | private EventMapper eventMapper; |
| | | |
| | | @Override |
| | | protected JpaRepository<Event, Long> getRepository() { |
| | | return this.eventRepository; |
| | | } |
| | | |
| | | // Event 등록 |
| | | @Override |
| | | @Transactional |
| | | public Event addEvent(EventForm eventForm) { |
| | | // Event 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(eventForm.getTitle(), eventForm.getDescription()); |
| | | |
| | | eventForm.setStatus(Event.INACTIVATION); |
| | | Event event = ConvertUtil.copyProperties(eventForm, Event.class); |
| | | |
| | | return this.eventRepository.saveAndFlush(event); |
| | | } |
| | | |
| | | // Event 제목 및 내용 공백 체크 |
| | | private void verifyTitleAndDescription(String title, String description) { |
| | | if (StringUtils.isEmpty(title) || StringUtils.isEmpty(description)) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EVENT_EMPTY_CONTENT)); |
| | | } |
| | | } |
| | | |
| | | // Event 조회 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<EventVo> findEvent(Map<String, Object> resJsonData, |
| | | EventCondition eventCondition, Pageable pageable) { |
| | | |
| | | eventCondition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | eventCondition.setPageSize(pageable.getPageSize()); |
| | | eventCondition.setTitle(eventCondition.getTitle()); |
| | | |
| | | List<Map<String, Object>> results = this.eventMapper.find(eventCondition); |
| | | Long totalCount = this.eventMapper.count(eventCondition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | List<EventVo> eventVos = ConvertUtil.convertListToListClass(results, EventVo.class); |
| | | |
| | | for (EventVo eventVo : eventVos) { |
| | | Boolean bActivation = false; |
| | | |
| | | if(eventVo.getStatus().equals(Event.ACTIVATION)) { |
| | | bActivation = true; |
| | | } |
| | | eventVo.activation = bActivation; |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, eventVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | return eventVos; |
| | | } |
| | | |
| | | // Event 수정 |
| | | @Override |
| | | @Transactional |
| | | public Event modifyEvent(EventForm eventForm) { |
| | | // Event 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(eventForm.getTitle(), eventForm.getDescription()); |
| | | |
| | | Event event = this.getEvent(eventForm.getId()); |
| | | ConvertUtil.copyProperties(eventForm, event, "id"); |
| | | |
| | | return this.eventRepository.saveAndFlush(event); |
| | | } |
| | | |
| | | // Event 수정 |
| | | @Override |
| | | @Transactional |
| | | public Event activeEvent(EventForm eventForm) { |
| | | |
| | | boolean bActivation = eventForm.getActivation(); |
| | | |
| | | if(bActivation) { |
| | | eventForm.setStatus(Event.ACTIVATION); |
| | | } else { |
| | | eventForm.setStatus(Event.INACTIVATION); |
| | | } |
| | | |
| | | Event event = this.getEvent(eventForm.getId()); |
| | | ConvertUtil.copyProperties(eventForm, event, "id"); |
| | | |
| | | if(bActivation) { |
| | | this.eventRepository.updateInActivation(eventForm.getId()); |
| | | } |
| | | |
| | | return this.eventRepository.saveAndFlush(event); |
| | | } |
| | | |
| | | // Event을 id 로 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Event getEvent(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EVENT_NOT_EXIST)); |
| | | } |
| | | |
| | | Event event = this.findOne(id); |
| | | |
| | | if (event == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EVENT_NOT_EXIST)); |
| | | } |
| | | |
| | | return event; |
| | | } |
| | | |
| | | // Event 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailEvent(Map<String, Object> resJsonData, EventCondition eventCondition) { |
| | | EventVo eventVo = new EventVo(); |
| | | |
| | | if (eventCondition.getId() != null) { |
| | | Event event = this.getEvent(eventCondition.getId()); |
| | | eventVo = ConvertUtil.copyProperties(event, EventVo.class); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, eventVo); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.config.kafka.KafkaSender; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.Faq; |
| | | import kr.wisestone.owl.domain.Guide; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.FaqMapper; |
| | | import kr.wisestone.owl.repository.FaqRepository; |
| | | import kr.wisestone.owl.service.FaqService; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.FaqVo; |
| | | import kr.wisestone.owl.vo.ResPage; |
| | | import kr.wisestone.owl.web.condition.FaqCondition; |
| | | import kr.wisestone.owl.web.form.FaqForm; |
| | | import kr.wisestone.owl.web.form.GuideForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class FaqServiceImpl extends AbstractServiceImpl<Faq, Long, JpaRepository<Faq, Long>> implements FaqService { |
| | | |
| | | @Autowired |
| | | private FaqRepository faqRepository; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private KafkaSender kafkaSender; |
| | | |
| | | @Autowired |
| | | private FaqMapper faqMapper; |
| | | |
| | | @Override |
| | | protected JpaRepository<Faq, Long> getRepository() { |
| | | return this.faqRepository; |
| | | } |
| | | |
| | | // 공지 사항 등록 |
| | | @Override |
| | | @Transactional |
| | | public Faq addFaq(FaqForm faqForm) { |
| | | // faq 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(faqForm.getTitle(), faqForm.getDescription()); |
| | | |
| | | faqForm.setStatus(Faq.INACTIVATION); |
| | | Faq faq = ConvertUtil.copyProperties(faqForm, Faq.class); |
| | | |
| | | return this.faqRepository.saveAndFlush(faq); |
| | | } |
| | | |
| | | // faq 제목 및 내용 공백 체크 |
| | | private void verifyTitleAndDescription(String title, String description) { |
| | | if (StringUtils.isEmpty(title) || StringUtils.isEmpty(description)) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.FAQ_EMPTY_CONTENT)); |
| | | } |
| | | } |
| | | |
| | | // faq 조회 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<FaqVo> findFaq(Map<String, Object> resJsonData, |
| | | FaqCondition faqCondition, Pageable pageable) { |
| | | |
| | | faqCondition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | faqCondition.setPageSize(pageable.getPageSize()); |
| | | faqCondition.setTitle(faqCondition.getTitle()); |
| | | |
| | | List<Map<String, Object>> results = this.faqMapper.find(faqCondition); |
| | | Long totalCount = this.faqMapper.count(faqCondition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | List<FaqVo> faqVos = ConvertUtil.convertListToListClass(results, FaqVo.class); |
| | | |
| | | // faq 아이디 1 은 관리자 - 관리자만 수정 가능 |
| | | for (FaqVo faqVo : faqVos) { |
| | | Boolean bActivation = false; |
| | | |
| | | if(faqVo.getStatus().equals(Faq.ACTIVATION)) { |
| | | bActivation = true; |
| | | } |
| | | faqVo.activation = bActivation; |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, faqVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | return faqVos; |
| | | } |
| | | |
| | | // faq 수정 |
| | | @Override |
| | | @Transactional |
| | | public Faq modifyFaq(FaqForm faqForm) { |
| | | // 공지사항 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(faqForm.getTitle(), faqForm.getDescription()); |
| | | |
| | | Faq faq = this.getFaq(faqForm.getId()); |
| | | ConvertUtil.copyProperties(faqForm, faq, "id"); |
| | | |
| | | return this.faqRepository.saveAndFlush(faq); |
| | | } |
| | | |
| | | // faq 수정 |
| | | @Override |
| | | @Transactional |
| | | public Faq activeFaq(FaqForm faqForm) { |
| | | |
| | | boolean bActivation = faqForm.getActivation(); |
| | | |
| | | if(bActivation) { |
| | | faqForm.setStatus(Faq.ACTIVATION); |
| | | } else { |
| | | faqForm.setStatus(Faq.INACTIVATION); |
| | | } |
| | | |
| | | Faq faq = this.getFaq(faqForm.getId()); |
| | | ConvertUtil.copyProperties(faqForm, faq, "id"); |
| | | |
| | | return this.faqRepository.saveAndFlush(faq); |
| | | } |
| | | |
| | | // faq id 로 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Faq getFaq(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.FAQ_NOT_EXIST)); |
| | | } |
| | | |
| | | Faq faq = this.findOne(id); |
| | | |
| | | if (faq == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.FAQ_NOT_EXIST)); |
| | | } |
| | | |
| | | return faq; |
| | | } |
| | | |
| | | // faq 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailFaq(Map<String, Object> resJsonData, FaqCondition faqCondition) { |
| | | FaqVo faqVo = new FaqVo(); |
| | | |
| | | if (faqCondition.getId() != null) { |
| | | Faq faq = this.getFaq(faqCondition.getId()); |
| | | faqVo = ConvertUtil.copyProperties(faq, FaqVo.class); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, faqVo); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.common.ExcelConditionCheck; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.ElasticSearchConstants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.domain.enumType.EmailType; |
| | | import kr.wisestone.owl.domain.enumType.IssueHistoryType; |
| | | import kr.wisestone.owl.domain.enumType.IssueStatusType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.IssueMapper; |
| | | import kr.wisestone.owl.mapper.ProjectMapper; |
| | | import kr.wisestone.owl.repository.IssueRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.*; |
| | | import kr.wisestone.owl.util.DateUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueTypeCustomFieldCondition; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.IssueCommentForm; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.commons.lang3.time.StopWatch; |
| | | import org.apache.poi.ss.usermodel.*; |
| | | import org.jsoup.Jsoup; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.messaging.simp.SimpMessagingTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class GanttServiceImpl extends AbstractServiceImpl<Issue, Long, JpaRepository<Issue, Long>> implements GanttService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(GanttServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueRepository issueRepository; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Override |
| | | protected JpaRepository<Issue, Long> getRepository() { |
| | | return this.issueRepository; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void addIssueVersion(Long id) { |
| | | issueService.addIssueVersion(id); |
| | | } |
| | | |
| | | |
| | | // 이슈를 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public Issue addIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) { |
| | | return issueService.addIssue(issueForm, multipartFiles); |
| | | } |
| | | |
| | | // 이슈 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | IssueCondition issueCondition, Pageable pageable) { |
| | | |
| | | return issueService.findChartIssue(resJsonData, issueCondition, pageable); |
| | | } |
| | | |
| | | // 이슈 목록을 조회한다(프로젝트용) |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | ProjectCondition projectCondition, Pageable pageable) { |
| | | |
| | | return issueService.findChartIssue(resJsonData, projectCondition, pageable); |
| | | } |
| | | |
| | | // 이슈 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition) { |
| | | issueService.detailIssue(resJsonData, issueCondition); |
| | | } |
| | | |
| | | // 이슈를 수정한다. |
| | | @Override |
| | | @Transactional |
| | | public Issue modifyIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) { |
| | | return issueService.modifyIssue(issueForm, multipartFiles); |
| | | } |
| | | |
| | | // 이슈를 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssues(IssueForm issueForm) { |
| | | issueService.removeIssues(issueForm); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.Guide; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.GuideMapper; |
| | | import kr.wisestone.owl.repository.GuideRepository; |
| | | import kr.wisestone.owl.service.GuideService; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.GuideVo; |
| | | import kr.wisestone.owl.vo.ManageUserVo; |
| | | import kr.wisestone.owl.vo.ResPage; |
| | | import kr.wisestone.owl.web.condition.GuideCondition; |
| | | import kr.wisestone.owl.web.form.GuideForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class GuideServiceImpl extends AbstractServiceImpl<Guide, Long, JpaRepository<Guide, Long>> implements GuideService { |
| | | |
| | | @Autowired |
| | | private GuideRepository guideRepository; |
| | | |
| | | @Autowired |
| | | private GuideMapper guideMapper; |
| | | |
| | | @Override |
| | | protected JpaRepository<Guide, Long> getRepository() { |
| | | return this.guideRepository; |
| | | } |
| | | |
| | | // guide 등록 |
| | | @Override |
| | | @Transactional |
| | | public Guide addGuide(GuideForm guideForm) { |
| | | // guide 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(guideForm.getTitle(), guideForm.getDescription()); |
| | | |
| | | guideForm.setStatus(Guide.INACTIVATION); |
| | | Guide guide = ConvertUtil.copyProperties(guideForm, Guide.class); |
| | | |
| | | return this.guideRepository.saveAndFlush(guide); |
| | | } |
| | | |
| | | // guide 제목 및 내용 공백 체크 |
| | | private void verifyTitleAndDescription(String title, String description) { |
| | | if (StringUtils.isEmpty(title) || StringUtils.isEmpty(description)) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.GUIDE_EMPTY_CONTENT)); |
| | | } |
| | | } |
| | | |
| | | // guide 조회 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<GuideVo> findGuide(Map<String, Object> resJsonData, |
| | | GuideCondition guideCondition, Pageable pageable) { |
| | | |
| | | guideCondition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | guideCondition.setPageSize(pageable.getPageSize()); |
| | | guideCondition.setTitle(guideCondition.getTitle()); |
| | | |
| | | List<Map<String, Object>> results = this.guideMapper.find(guideCondition); |
| | | Long totalCount = this.guideMapper.count(guideCondition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | List<GuideVo> guideVos = ConvertUtil.convertListToListClass(results, GuideVo.class); |
| | | |
| | | for (GuideVo guideVo : guideVos) { |
| | | Boolean bActivation = false; |
| | | |
| | | if(guideVo.getStatus().equals(Guide.ACTIVATION)) { |
| | | bActivation = true; |
| | | } |
| | | guideVo.activation = bActivation; |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, guideVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | return guideVos; |
| | | } |
| | | |
| | | // guide 수정 |
| | | @Override |
| | | @Transactional |
| | | public Guide modifyGuide(GuideForm guideForm) { |
| | | // guide 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(guideForm.getTitle(), guideForm.getDescription()); |
| | | |
| | | Guide guide = this.getGuide(guideForm.getId()); |
| | | ConvertUtil.copyProperties(guideForm, guide, "id"); |
| | | |
| | | return this.guideRepository.saveAndFlush(guide); |
| | | } |
| | | |
| | | // guide 수정 |
| | | @Override |
| | | @Transactional |
| | | public Guide activeGuide(GuideForm guideForm) { |
| | | |
| | | boolean bActivation = guideForm.getActivation(); |
| | | |
| | | if(bActivation) { |
| | | guideForm.setStatus(Guide.ACTIVATION); |
| | | } else { |
| | | guideForm.setStatus(Guide.INACTIVATION); |
| | | } |
| | | |
| | | Guide guide = this.getGuide(guideForm.getId()); |
| | | ConvertUtil.copyProperties(guideForm, guide, "id"); |
| | | |
| | | if(bActivation) { |
| | | this.guideRepository.updateInActivation(guideForm.getId()); |
| | | } |
| | | |
| | | return this.guideRepository.saveAndFlush(guide); |
| | | } |
| | | |
| | | // guide을 id 로 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Guide getGuide(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.GUIDE_NOT_EXIST)); |
| | | } |
| | | |
| | | Guide guide = this.findOne(id); |
| | | |
| | | if (guide == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.GUIDE_NOT_EXIST)); |
| | | } |
| | | |
| | | return guide; |
| | | } |
| | | |
| | | // guide 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailGuide(Map<String, Object> resJsonData, GuideCondition guideCondition) { |
| | | GuideVo guideVo = new GuideVo(); |
| | | |
| | | if (guideCondition.getId() != null) { |
| | | Guide guide = this.getGuide(guideCondition.getId()); |
| | | guideVo = ConvertUtil.copyProperties(guide, GuideVo.class); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, guideVo); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueComment; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.IssueCommentRepository; |
| | | import kr.wisestone.owl.service.IssueCommentService; |
| | | import kr.wisestone.owl.service.IssueService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.IssueCommentVo; |
| | | import kr.wisestone.owl.vo.UserVo; |
| | | import kr.wisestone.owl.web.form.IssueCommentForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class IssueCommentServiceImpl extends AbstractServiceImpl<IssueComment, Long, JpaRepository<IssueComment, Long>> |
| | | implements IssueCommentService { |
| | | |
| | | static final Logger log = LoggerFactory.getLogger(IssueCommentServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueCommentRepository issueCommentRepository; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueComment, Long> getRepository() { |
| | | return this.issueCommentRepository; |
| | | } |
| | | |
| | | // 댓글을 등록한다. |
| | | @Override |
| | | @Transactional |
| | | public IssueComment addIssueComment(IssueCommentForm issueCommentForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | IssueComment issueComment = ConvertUtil.copyProperties(issueCommentForm, IssueComment.class); |
| | | |
| | | this.verifyComment(issueCommentForm.getDescription()); |
| | | |
| | | Issue issue = this.issueService.getIssue(issueCommentForm.getIssueId()); |
| | | issueComment.setIssue(issue); |
| | | issueComment.setWorkspace(issue.getProject().getWorkspace()); |
| | | |
| | | this.issueCommentRepository.saveAndFlush(issueComment); |
| | | |
| | | return issueComment; |
| | | } |
| | | |
| | | private void verifyComment(String comment) { |
| | | if (StringUtils.isEmpty(comment)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_COMMENT_NOT_COMMENT)); |
| | | } |
| | | |
| | | if (comment.length() > 300) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_COMMENT_MAX_LENGTH_OUT)); |
| | | } |
| | | } |
| | | |
| | | // 댓글을 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssueComments(IssueCommentForm issueCommentForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | if (issueCommentForm.getRemoveIds().size() < 1) { |
| | | throw new OwlRuntimeException(MsgConstants.ISSUE_COMMENT_REMOVE_NOT_SELECT); |
| | | } |
| | | |
| | | for (Long issueCommentId : issueCommentForm.getRemoveIds()) { |
| | | this.removeIssueComments(issueCommentId); |
| | | } |
| | | |
| | | this.issueCommentRepository.flush(); |
| | | } |
| | | |
| | | // 댓글을 삭제한다. |
| | | private void removeIssueComments(Long issueCommentId) { |
| | | IssueComment issueComment = this.getIssueComment(issueCommentId); |
| | | // 댓글 삭제 권한 체크 |
| | | this.checkRemovePermission(issueComment); |
| | | |
| | | this.issueCommentRepository.delete(issueComment); |
| | | } |
| | | |
| | | // 댓글 삭제 권한이 있는지 체크한다. |
| | | private void checkRemovePermission(IssueComment issueComment) { |
| | | UserVo userVo = this.webAppUtil.getLoginUser(); |
| | | |
| | | if (!issueComment.getRegisterId().equals(userVo.getId())) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_COMMENT_NOT_REMOVE_PERMISSION)); |
| | | } |
| | | } |
| | | |
| | | // 댓글 아이디로 댓글을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueComment getIssueComment(Long id ) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_COMMENT_NOT_EXIST)); |
| | | } |
| | | |
| | | IssueComment issueComment = this.findOne(id); |
| | | |
| | | if (issueComment == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_COMMENT_NOT_EXIST)); |
| | | } |
| | | |
| | | return issueComment; |
| | | } |
| | | |
| | | // 이슈에 등록된 댓글 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueCommentVo> findIssueComment(Long issueId) { |
| | | return this.issueCommentRepository.findByIssueId(issueId); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.domain.enumType.IssueHistoryType; |
| | | import kr.wisestone.owl.mapper.IssueCustomFieldValueMapper; |
| | | import kr.wisestone.owl.repository.IssueCustomFieldValueRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.CustomFieldVo; |
| | | import kr.wisestone.owl.vo.IssueCustomFieldValueVo; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class IssueCustomFieldValueServiceImpl extends AbstractServiceImpl<IssueCustomFieldValue, Long, JpaRepository<IssueCustomFieldValue, Long>> implements IssueCustomFieldValueService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueCustomFieldValueServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueCustomFieldValueRepository issueCustomFieldValueRepository; |
| | | |
| | | @Autowired |
| | | private CustomFieldService customFieldService; |
| | | |
| | | @Autowired |
| | | private IssueHistoryService issueHistoryService; |
| | | |
| | | @Autowired |
| | | private IssueCustomFieldValueMapper issueCustomFieldValueMapper; |
| | | |
| | | @Autowired |
| | | private IssueTypeCustomFieldService issueTypeCustomFieldService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueCustomFieldValue, Long> getRepository() { |
| | | return this.issueCustomFieldValueRepository; |
| | | } |
| | | |
| | | // 이슈에서 사용되는 사용자 정의 필드 값을 업데이트한다. |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueCustomFieldValue(Issue issue, List<Map<String, Object>> issueCustomFields) { |
| | | // 전체 이슈에 사용되는 사용자 정의 필드 값 삭제 |
| | | issue.getIssueCustomFieldValues().clear(); |
| | | List<IssueCustomFieldValue> issueCustomFieldValues = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> map : issueCustomFields) { |
| | | Map<String, Object> result = new HashMap<>(); |
| | | // customFieldVo 에서 사용자 정의 필드와 이슈 유형에 연결된 사용자 정의 필드 정보를 가져온다. |
| | | this.getCustomFieldAndIssueTypeCustomField(map, issue, result); |
| | | List<String> useValues = MapUtil.getStrings(map, "useValues"); |
| | | |
| | | if (useValues != null) { |
| | | for (String useValue : useValues) { |
| | | if (!StringUtils.isEmpty(useValue)) { |
| | | // Xss 공격 방어를 위해 script 공백으로 치환 |
| | | IssueCustomFieldValue issueCustomFieldValue = new IssueCustomFieldValue(issue, (CustomField)result.get("customField"), (IssueTypeCustomField)result.get("issueTypeCustomField"), useValue); |
| | | issueCustomFieldValues.add(issueCustomFieldValue); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (issueCustomFieldValues.size() > 0) { |
| | | this.issueCustomFieldValueRepository.saveAll(issueCustomFieldValues); |
| | | } |
| | | } |
| | | |
| | | // customFieldVo 에서 사용자 정의 필드와 이슈 유형에 연결된 사용자 정의 필드 정보를 가져온다. |
| | | @Override |
| | | public void getCustomFieldAndIssueTypeCustomField(Map<String, Object> map, Issue issue, Map<String, Object> result) { |
| | | Map<String, Object> customFieldMap = (Map<String, Object>) MapUtil.getObject(map, "customFieldVo"); |
| | | CustomField customField = this.customFieldService.getCustomField(MapUtil.getLong(customFieldMap, "id")); |
| | | IssueTypeCustomField issueTypeCustomField = this.issueTypeCustomFieldService.findByProjectIdAndIssueTypeIdAndCustomFieldId(issue.getProject().getId(), issue.getIssueType().getId(), customField.getId()); |
| | | |
| | | result.put("customField", customField); |
| | | result.put("issueTypeCustomField", issueTypeCustomField); |
| | | } |
| | | |
| | | // 이슈에 연결된 사용자 정의 필드 값을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueCustomFieldValueVo> findByIssueId(Long issueId) { |
| | | List<IssueCustomFieldValueVo> issueCustomFieldValueVos = Lists.newArrayList(); |
| | | List<IssueCustomFieldValue> issueCustomFieldValues = this.issueCustomFieldValueRepository.findByIssueId(issueId); |
| | | |
| | | for (IssueCustomFieldValue issueCustomFieldValue : issueCustomFieldValues) { |
| | | IssueCustomFieldValueVo issueCustomFieldValueVo = ConvertUtil.copyProperties(issueCustomFieldValue, IssueCustomFieldValueVo.class); |
| | | CustomFieldVo customFieldVo = ConvertUtil.copyProperties(issueCustomFieldValue.getCustomField(), CustomFieldVo.class); |
| | | customFieldVo.setCustomFieldType(issueCustomFieldValue.getCustomField().getCustomFieldType().toString()); |
| | | issueCustomFieldValueVo.setCustomFieldVo(customFieldVo); |
| | | issueCustomFieldValueVos.add(issueCustomFieldValueVo); |
| | | } |
| | | |
| | | return issueCustomFieldValueVos; |
| | | } |
| | | |
| | | // 사용자 정의 필드 옵션 값이 변경되었을 때 사용자 정의 필드 값을 사용하는 이슈에서 해당 값이 존재하는지 확인하고 없어졌으면 삭제해준다. |
| | | @Override |
| | | @Transactional |
| | | public void checkExistIssueCustomFieldValue(CustomField customField, List<String> values, CustomFieldType oldCustomFieldType) { |
| | | |
| | | List<IssueCustomFieldValue> removeIssueCustomFieldValues = Lists.newArrayList(); |
| | | Map<String, Object> issueMaps = new HashMap<>(); // 이력을 남길 이슈 추출 |
| | | |
| | | // 이슈에서 사용되는 사용자 정의 필드 값 정보를 추출한다. |
| | | this.saveOriginalIssueCustomFieldValues(customField, values, issueMaps, removeIssueCustomFieldValues); |
| | | |
| | | // 삭제할 값 삭제 |
| | | if (removeIssueCustomFieldValues.size() > 0) { |
| | | this.issueCustomFieldValueRepository.deleteInBatch(removeIssueCustomFieldValues); |
| | | // 삭제 후 남은 이슈 사용자 정의 필드 값 정보를 issueMaps 에 저장한다. |
| | | this.saveNewIssueCustomFieldValues(customField, issueMaps); |
| | | // 변경된 이슈 사용자 정의 필드 값 정보를 히스토리로 남긴다. |
| | | this.saveIssueCustomFieldValueHistory(issueMaps, customField, oldCustomFieldType); |
| | | } |
| | | } |
| | | |
| | | // 이슈에서 사용되는 사용자 정의 필드 값 정보를 추출한다. |
| | | private void saveOriginalIssueCustomFieldValues(CustomField customField, List<String> values, Map<String, Object> issueMaps, List<IssueCustomFieldValue> removeIssueCustomFieldValues) { |
| | | // 해당 사용자 정의 필드를 사용하고 있는 이슈 정보를 추출한다. |
| | | List<IssueCustomFieldValue> issueCustomFieldValues = this.findByCustomFieldId(customField); |
| | | |
| | | // 각 이슈의 이전 값 추출 |
| | | for (IssueCustomFieldValue issueCustomFieldValue : issueCustomFieldValues) { |
| | | Boolean existValue = false; |
| | | |
| | | for (String value : values) { |
| | | if (issueCustomFieldValue.getUseValue().equals(value)) { |
| | | existValue = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!existValue) { |
| | | // 삭제할 값 |
| | | removeIssueCustomFieldValues.add(issueCustomFieldValue); |
| | | } |
| | | |
| | | String issueId = issueCustomFieldValue.getIssue().getId().toString(); |
| | | |
| | | if (MapUtil.getObject(issueMaps, issueId) == null) { |
| | | Map<String, Object> issue = new HashMap<>(); |
| | | issue.put("issue", issueCustomFieldValue.getIssue()); |
| | | issue.put("oldValues", Lists.newArrayList(issueCustomFieldValue.getUseValue())); |
| | | issue.put("newValues", Lists.newArrayList()); |
| | | |
| | | issueMaps.put(issueId, issue); |
| | | } |
| | | else { |
| | | Map<String, Object> issue = (Map<String, Object>) issueMaps.get(issueId); |
| | | List<String> oldValues = (List<String>) MapUtil.getObject(issue, "oldValues"); |
| | | oldValues.add(issueCustomFieldValue.getUseValue()); |
| | | issue.put("oldValues", oldValues); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 삭제 후 남은 이슈 사용자 정의 필드 값 정보를 issueMaps 에 저장한다. |
| | | private void saveNewIssueCustomFieldValues(CustomField customField, Map<String, Object> issueMaps) { |
| | | // 삭제 후 다시 이슈 사용자 정의 필드 값을 조회한다. |
| | | List<IssueCustomFieldValue> newIssueCustomFieldValues = this.findByCustomFieldId(customField); |
| | | |
| | | for (IssueCustomFieldValue newIssueCustomFieldValue : newIssueCustomFieldValues) { |
| | | String issueId = newIssueCustomFieldValue.getIssue().getId().toString(); |
| | | |
| | | if (MapUtil.getObject(issueMaps, issueId) != null) { |
| | | Map<String, Object> issue = (Map<String, Object>) issueMaps.get(issueId); |
| | | List<String> newValues = (List<String>) MapUtil.getObject(issue, "newValues"); |
| | | newValues.add(newIssueCustomFieldValue.getUseValue()); |
| | | issue.put("newValues", newValues); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 변경된 이슈 사용자 정의 필드 값 정보를 히스토리로 남긴다. |
| | | private void saveIssueCustomFieldValueHistory(Map<String, Object> issueMaps, CustomField customField, CustomFieldType oldCustomFieldType) { |
| | | Iterator<String> iterator = issueMaps.keySet().iterator(); |
| | | |
| | | while (iterator.hasNext()) { |
| | | StringBuilder issueChangeDescription = new StringBuilder(); |
| | | Map<String, Object> issueMap = (Map<String, Object>) issueMaps.get(iterator.next()); |
| | | Issue issue = (Issue) MapUtil.getObject(issueMap, "issue"); |
| | | List<String> oldValues = (List<String>) MapUtil.getObject(issueMap, "oldValues"); |
| | | List<String> newValues = (List<String>) MapUtil.getObject(issueMap, "newValues"); |
| | | |
| | | // 배열에 있는 값을 보기 좋게 추출한다. |
| | | StringBuilder oldValueString = this.setValueString(oldValues); |
| | | StringBuilder newValueString = this.setValueString(newValues); |
| | | |
| | | // 이슈 사용자 정의 필드 값이 변경되었는지 확인한다. |
| | | if (this.checkChangeIssueCustomFieldValues(oldValueString, newValueString)) { |
| | | continue; |
| | | } |
| | | |
| | | // 값이 비었을 때 값이 없다는 글자를 남겨준다. |
| | | this.setEmptyString(oldValueString, oldCustomFieldType); |
| | | // 값이 비었을 때 값이 없다는 글자를 남겨준다. |
| | | this.setEmptyString(newValueString, oldCustomFieldType); |
| | | |
| | | // 이전에 문자열필드였다가 다른 필드로 변경한 경우나 이전에 문자열 필드가 아니었다가 문자열 필드로 바뀐 경우 |
| | | if (CustomFieldType.INPUT.equals(oldCustomFieldType) && !customField.getCustomFieldType().equals(CustomFieldType.INPUT) || |
| | | !CustomFieldType.INPUT.equals(oldCustomFieldType) && customField.getCustomFieldType().equals(CustomFieldType.INPUT)) { |
| | | // 사용자 정의 필드 유형이 변경되어 이슈에서 사용된 옵션 값이 삭제되었다고 저장한다. |
| | | this.issueHistoryService.recodeChangeCustomFieldType(customField, oldValueString.toString(), issueChangeDescription); |
| | | } |
| | | else { |
| | | // 사용자 정의 필드의 옵션 값이 삭제되어 이슈에서 사용된 값이 삭제될 경우 변경 정보를 저장한다. |
| | | this.issueHistoryService.recodeRemoveCustomFieldOptionValue(customField, oldValueString.toString(), newValueString.toString(), issueChangeDescription); |
| | | } |
| | | |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.MODIFY, issueChangeDescription.toString()); |
| | | } |
| | | } |
| | | |
| | | // 배열에 있는 값을 보기 좋게 추출한다. |
| | | private StringBuilder setValueString(List<String> values) { |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | for (String value : values) { |
| | | stringBuilder.append(value); |
| | | stringBuilder.append(", "); |
| | | } |
| | | |
| | | return stringBuilder; |
| | | } |
| | | |
| | | // 값이 비었을 때 값이 없다는 글자를 남겨준다. |
| | | private void setEmptyString(StringBuilder stringBuilder, CustomFieldType customFieldType) { |
| | | if (stringBuilder.toString().equals("")) { |
| | | if (CustomFieldType.INPUT.equals(customFieldType)) { |
| | | stringBuilder.append("<span translate=\"common.noValueEntered\">입력한 값이 없습니다.</span>"); |
| | | } |
| | | else { |
| | | stringBuilder.append("<span translate=\"common.noValueSelected\">선택한 값이 없습니다.</span>"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈 사용자 정의 필드 값이 변경되었는지 확인한다. |
| | | private boolean checkChangeIssueCustomFieldValues(StringBuilder oldValueString, StringBuilder newValueString) { |
| | | if (oldValueString.toString().equals(newValueString.toString())) { |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | // 사용자 정의 필드를 사용하고 있는 값 정보를 추출한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueCustomFieldValue> findByCustomFieldId(CustomField customField) { |
| | | return this.issueCustomFieldValueRepository.findByCustomFieldId(customField.getId()); |
| | | } |
| | | |
| | | // 프로젝트에 사용자 정의 필드 연결이 해제될 경우 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssueCustomFieldValue(Long issueTypeCustomFieldId) { |
| | | this.issueCustomFieldValueMapper.deleteIssueCustomFieldValue(issueTypeCustomFieldId); |
| | | } |
| | | |
| | | // 사용자 정의 필드 값을 저장한 이슈를 찾는다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public boolean find(IssueCondition condition, Set<String> issueIds) { |
| | | boolean customFieldSearch = false; |
| | | int firstCount = 0; |
| | | |
| | | Set<String> tempIssueIds = new HashSet<>(); |
| | | |
| | | for (Map<String, Object> customField : condition.getIssueCustomFields()) { |
| | | IssueCustomFieldValueCondition issueCustomFieldValueCondition = IssueCustomFieldValueCondition.make(customField); |
| | | |
| | | if (issueCustomFieldValueCondition.getUseValues().size() > 0 || !StringUtils.isEmpty(issueCustomFieldValueCondition.getUseValue())) { |
| | | issueCustomFieldValueCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | issueCustomFieldValueCondition.setCustomFieldId(MapUtil.getLong(customField, "id")); |
| | | |
| | | // 사용자 정의 필드 값 검색 시작 |
| | | customFieldSearch = true; |
| | | Map<String, Object> result = new HashMap<>(); |
| | | |
| | | switch (CustomFieldType.valueOf(issueCustomFieldValueCondition.getCustomFieldType())) { |
| | | case INPUT: |
| | | result = this.issueCustomFieldValueMapper.findLikeUseValue(issueCustomFieldValueCondition); |
| | | break; |
| | | case MULTI_SELECT: |
| | | case SINGLE_SELECT: |
| | | result = this.issueCustomFieldValueMapper.findByUseValue(issueCustomFieldValueCondition); |
| | | break; |
| | | } |
| | | |
| | | String issueIdList = MapUtil.getString(result, "issueIds"); |
| | | |
| | | if (!StringUtils.isEmpty(issueIdList)) { |
| | | Set<String> results = new HashSet<>(Arrays.asList(issueIdList.split(","))); |
| | | |
| | | if (firstCount > 0) { |
| | | Set<String> commonKeys = new HashSet<>(tempIssueIds); |
| | | commonKeys.retainAll(results); |
| | | tempIssueIds = commonKeys; |
| | | } |
| | | else { |
| | | tempIssueIds = results; |
| | | } |
| | | } |
| | | |
| | | firstCount++; |
| | | } |
| | | } |
| | | |
| | | issueIds.addAll(tempIssueIds); |
| | | |
| | | return customFieldSearch; |
| | | } |
| | | |
| | | // 이슈에서 저장한 사용자 정의 필드 값을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Map<String, Object>> findInIssueIds(IssueCondition issueCondition) { |
| | | return this.issueCustomFieldValueMapper.findInIssueIds(issueCondition); |
| | | } |
| | | |
| | | // 이슈에서 저장된 해당 사용자 정의 필드 값을 모두 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssueCustomFieldValuesByCustomFieldId(CustomField customField) { |
| | | // 사용자 정의 필드를 사용하고 있는 값 정보를 추출한다. |
| | | List<IssueCustomFieldValue> issueCustomFieldValues = this.findByCustomFieldId(customField); |
| | | List<Long> ids = Lists.newArrayList(); |
| | | |
| | | for (IssueCustomFieldValue issueCustomFieldValue : issueCustomFieldValues) { |
| | | ids.add(issueCustomFieldValue.getId()); |
| | | } |
| | | |
| | | if (ids.size() > 0) { |
| | | this.issueCustomFieldValueMapper.deleteByIssueCustomFieldValueId(ids); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.ElasticSearchConstants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.domain.enumType.IssueHistoryType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.IssueHistoryMapper; |
| | | import kr.wisestone.owl.repository.IssueHistoryRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.*; |
| | | import kr.wisestone.owl.vo.IssueHistoryVo; |
| | | import kr.wisestone.owl.web.condition.IssueHistoryCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class IssueHistoryServiceImpl extends AbstractServiceImpl<IssueHistory, Long, JpaRepository<IssueHistory, Long>> implements IssueHistoryService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueHistoryServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueHistoryRepository issueHistoryRepository; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private IssueHistoryMapper issueHistoryMapper; |
| | | |
| | | @Autowired |
| | | private IssueRiskService issueRiskService; |
| | | |
| | | @Autowired |
| | | private IssueCustomFieldValueService issueCustomFieldValueService; |
| | | |
| | | @Value("${email.userName}") |
| | | private String systemEmail; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueHistory, Long> getRepository() { |
| | | return this.issueHistoryRepository; |
| | | } |
| | | |
| | | // 이력 생성 |
| | | @Override |
| | | @Transactional |
| | | public void addIssueHistory(Issue issue, IssueHistoryType issueHistoryType, String issueChangeDescription) { |
| | | IssueHistory issueHistory = new IssueHistory(); |
| | | issueHistory.setIssue(issue); |
| | | issueHistory.setProject(issue.getProject()); |
| | | issueHistory.setIssueHistoryType(issueHistoryType); |
| | | StringBuilder description = new StringBuilder(); |
| | | // 이력 정보를 만들어 낸다. |
| | | this.makeDescription(description, issueHistoryType, issueChangeDescription); |
| | | issueHistory.setDescription(description.toString()); |
| | | |
| | | this.issueHistoryRepository.saveAndFlush(issueHistory); |
| | | |
| | | // 비슷한 시간에 연속적으로 기록을 남겼는지 확인하고 발견된 기록을 묶어서 저장한다. |
| | | this.detectSameTimeIssueHistory(issue); |
| | | } |
| | | |
| | | // 이력 정보를 만들어 낸다. |
| | | @Override |
| | | public void makeDescription(StringBuilder description, IssueHistoryType issueHistoryType, String issueChangeDescription) { |
| | | description.append("<div class=\"activity-text\">"); |
| | | |
| | | // 생성, 수정, 삭제에 대해 기록을 남긴다. |
| | | switch (issueHistoryType) { |
| | | case ADD: |
| | | description.append("<h6 class=\"change\"><span class=\"dot\"></span><span translate=\"common.createIssue\">이슈 생성</span>"); |
| | | description.append("<span class='activity-timestamp'>"); |
| | | description.append(DateUtil.convertDateToStr(new Date())); |
| | | description.append(" ("); |
| | | description.append(this.webAppUtil.getLoginUser().getName()); |
| | | description.append(" - "); |
| | | description.append(CommonUtil.decryptAES128(this.webAppUtil.getLoginUser().getAccount())); |
| | | description.append(")"); |
| | | description.append("</span></h6>"); |
| | | break; |
| | | |
| | | case MODIFY: |
| | | description.append("<h6 class=\"creat\"><span class=\"dot\"></span><span translate=\"common.updateIssue\">이슈 변경</span>"); |
| | | description.append("<span class=\"activity-timestamp\">"); |
| | | description.append(DateUtil.convertDateToStr(new Date())); |
| | | description.append(" ("); |
| | | |
| | | if (this.webAppUtil.getLoginUser() != null) { |
| | | description.append(this.webAppUtil.getLoginUser().getName()); |
| | | description.append(" - "); |
| | | description.append(CommonUtil.decryptAES128(this.webAppUtil.getLoginUser().getAccount())); |
| | | } |
| | | else { |
| | | description.append("OWL-ITS-SYSTEM"); |
| | | description.append(" - "); |
| | | description.append(this.systemEmail); |
| | | } |
| | | |
| | | description.append(")"); |
| | | description.append("</span></h6>"); |
| | | description.append(issueChangeDescription); |
| | | break; |
| | | |
| | | case DELETE: |
| | | description.append("<h6 class=\"delete\"><span class=\"dot\"></span><span translate=\"common.deleteIssue\">이슈 삭제</span>"); |
| | | description.append("<span class=\"activity-timestamp\">"); |
| | | description.append(DateUtil.convertDateToStr(new Date())); |
| | | description.append(" ("); |
| | | description.append(this.webAppUtil.getLoginUser().getName()); |
| | | description.append(" - "); |
| | | description.append(CommonUtil.decryptAES128(this.webAppUtil.getLoginUser().getAccount())); |
| | | description.append(")"); |
| | | description.append("</span></h6>"); |
| | | break; |
| | | } |
| | | |
| | | description.append("</div>"); |
| | | } |
| | | |
| | | // 비슷한 시간에 연속적으로 기록을 남겼는지 확인하고 발견된 기록을 묶어서 저장한다. |
| | | private void detectSameTimeIssueHistory(Issue issue) { |
| | | StringBuilder description = new StringBuilder(); |
| | | List<IssueHistoryVo> issueHistoryVos = this.issueHistoryRepository.findByIssueId(issue.getId()); |
| | | List<IssueHistoryVo> saveIssueHistoryVos = Lists.newArrayList(); |
| | | |
| | | for (int count = 0; count < (issueHistoryVos.size() - 1); count++) { |
| | | IssueHistoryVo issueHistoryVo = issueHistoryVos.get(count); |
| | | IssueHistoryVo nextIssueHistoryVo = issueHistoryVos.get(count + 1); |
| | | |
| | | Date beginDate = DateUtil.convertStrToDate(issueHistoryVo.getRegisterDate()); |
| | | Date endDate = DateUtil.convertStrToDate(nextIssueHistoryVo.getRegisterDate()); |
| | | |
| | | long diff = beginDate.getTime() - endDate.getTime(); |
| | | // 1분 이내에 기록된 이슈 변경 내역은 합친다. |
| | | if ((diff/1000) < 61) { |
| | | // 중복된 이슈 이력이 있는지 확인하고 중복되지 않았으면 배열에 추가한다. |
| | | this.checkDuplicationHistoryList(saveIssueHistoryVos, issueHistoryVo); |
| | | // 중복된 이슈 이력이 있는지 확인하고 중복되지 않았으면 배열에 추가한다. |
| | | this.checkDuplicationHistoryList(saveIssueHistoryVos, nextIssueHistoryVo); |
| | | } |
| | | } |
| | | |
| | | List<Long> removeIds = Lists.newArrayList(); |
| | | |
| | | for (IssueHistoryVo issueHistoryVo : saveIssueHistoryVos) { |
| | | description.append(issueHistoryVo.getDescription()); |
| | | removeIds.add(issueHistoryVo.getId()); |
| | | } |
| | | |
| | | // 합친 기록 생성 |
| | | if (removeIds.size() > 0) { |
| | | Long lastUpdateIssueHistoryId = removeIds.get(removeIds.size() - 1); |
| | | // 마지막 대상에 기록을 옮긴다. |
| | | IssueHistory issueHistory = this.findOne(lastUpdateIssueHistoryId); |
| | | issueHistory.setIssueHistoryType(IssueHistoryType.TOTAL); |
| | | issueHistory.setDescription(description.toString()); |
| | | this.issueHistoryRepository.saveAndFlush(issueHistory); |
| | | |
| | | // 이전 기록 삭제 |
| | | for (Long removeId : removeIds) { |
| | | // 마지막 대상은 삭제하지 않는다. |
| | | if (!lastUpdateIssueHistoryId.equals(removeId)) { |
| | | this.issueHistoryRepository.deleteById(removeId); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 중복된 이슈 이력이 있는지 확인하고 중복되지 않았으면 배열에 추가한다. |
| | | private void checkDuplicationHistoryList(List<IssueHistoryVo> issueHistoryVos, IssueHistoryVo issueHistoryVo) { |
| | | boolean duplicate = false; |
| | | |
| | | for (IssueHistoryVo historyVo : issueHistoryVos) { |
| | | if (historyVo.getId().equals(issueHistoryVo.getId())) { |
| | | duplicate = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!duplicate) { |
| | | issueHistoryVos.add(issueHistoryVo); |
| | | } |
| | | } |
| | | |
| | | // 해당 사용자의 이슈 기록 정보를 가져온다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void findIssueHistory(Map<String, Object> resJsonData, IssueHistoryCondition issueHistoryCondition) { |
| | | // 조회하는 사용자 정보 |
| | | issueHistoryCondition.setUserId(this.webAppUtil.getLoginId()); |
| | | |
| | | if (StringUtils.isEmpty(issueHistoryCondition.getSearchPeriod())) { |
| | | issueHistoryCondition.setSearchPeriod(DateUtil.LAST_SEVEN_DAYS); |
| | | } |
| | | |
| | | // 검색 조건 직접 입력이 아닐 경우 |
| | | if (!issueHistoryCondition.getSearchPeriod().equals(DateUtil.CUSTOM_INPUT)) { |
| | | // 검색 일자를 구한다. |
| | | List<Date> searchDates = CommonUtil.findSearchPeriod(issueHistoryCondition.getSearchPeriod()); |
| | | |
| | | // 날짜가 검색되지 않았으면 오류 |
| | | if (searchDates.size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.WIDGET_SEARCH_DATE_NOT_FOUND)); |
| | | } |
| | | |
| | | // 검색 조건에 시작일, 종료일을 설정한다. |
| | | issueHistoryCondition.setSearchStartDate(DateUtil.convertDateToYYYYMMDD(searchDates.get(0))); |
| | | issueHistoryCondition.setSearchEndDate(DateUtil.convertDateToYYYYMMDD(DateUtil.addDays(searchDates.get(searchDates.size() - 1), 1))); |
| | | } |
| | | else { |
| | | issueHistoryCondition.setSearchStartDate(DateUtil.convertDateToStr(DateUtil.convertStrToDate(issueHistoryCondition.getSearchStartDate(), "yyyy-MM-dd"))); |
| | | issueHistoryCondition.setSearchEndDate(DateUtil.convertDateToStr(DateUtil.addDays(DateUtil.convertStrToDate(issueHistoryCondition.getSearchEndDate(), "yyyy-MM-dd"), 1))); |
| | | } |
| | | |
| | | List<Map<String, Object>> results = this.issueHistoryMapper.find(issueHistoryCondition); |
| | | |
| | | Map<String, Object> issueHistoryMaps = new HashMap<>(); |
| | | Map<String, Object> issueHistoryGroups = new HashMap<>(); |
| | | issueHistoryMaps.put("searchStartDate", issueHistoryCondition.getSearchStartDate()); |
| | | issueHistoryMaps.put("searchEndDate", issueHistoryCondition.getSearchEndDate()); |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | IssueHistoryVo issueHistoryVo = ConvertUtil.convertMapToClass(result, IssueHistoryVo.class); |
| | | List<IssueHistoryVo> issueHistoryVos = Lists.newArrayList(); |
| | | |
| | | String recodeDate = issueHistoryVo.getRegisterDate(); |
| | | |
| | | // 해당 요일에 정보가 없을 경우 배열을 만들어 이슈 기록 정보를 담는다. |
| | | if (MapUtil.getObject(issueHistoryGroups, recodeDate) == null) { |
| | | issueHistoryVos.add(issueHistoryVo); |
| | | issueHistoryGroups.put(recodeDate, issueHistoryVos); |
| | | } |
| | | else { |
| | | // 있을 경우에는 해당 배열을 가져와 이슈 기록 정보를 추가한다. |
| | | issueHistoryVos = (List<IssueHistoryVo>)MapUtil.getObject(issueHistoryGroups, recodeDate); |
| | | issueHistoryVos.add(issueHistoryVo); |
| | | } |
| | | |
| | | if (issueHistoryVos.size() > 0) { |
| | | issueHistoryGroups.put(recodeDate, issueHistoryVos); |
| | | } |
| | | } |
| | | |
| | | issueHistoryMaps.put("issueHistoryGroups", issueHistoryGroups); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueHistoryMaps); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_HISTORY_FIND)); |
| | | } |
| | | |
| | | |
| | | // 이슈 아이디에 해당하는 기록 정보를 가져온다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueHistoryVo> findIssueHistory(Long issueId) { |
| | | return this.issueHistoryRepository.findByIssueId(issueId); |
| | | } |
| | | |
| | | // 이슈 변경 내역을 추출한다. |
| | | @Override |
| | | public StringBuilder detectIssueChange(Issue issue, IssueForm issueForm, Project project, IssueStatus issueStatus, IssueType issueType, Priority priority, Severity severity, List<MultipartFile> files) { |
| | | StringBuilder description = new StringBuilder(); |
| | | |
| | | // 이슈 프로젝트 변경 정보를 기록한다. |
| | | this.detectProject(issue, issueForm, description, project); |
| | | // 이슈 중요도 변경 정보를 기록한다. |
| | | this.detectIssueSeverity(issue, issueForm, description, severity); |
| | | // 이슈 우선순위 변경 정보를 기록한다. |
| | | this.detectIssuePriority(issue, issueForm, description, priority); |
| | | // 이슈 상태 변경 정보를 기록한다. |
| | | this.detectIssueStatus(issue, issueForm, description, issueStatus); |
| | | // 이슈 타입 변경 정보를 기록한다. |
| | | this.detectIssueType(issue, issueForm, description, issueType); |
| | | // 이슈에 첨부된 파일에 대해 변경 정보를 기록한다. |
| | | this.detectAttachedFile(issueForm, description, files); |
| | | // 이슈 기간 변경 정보를 기록한다. |
| | | this.detectIssuePeriod(issue, issueForm, description); |
| | | // 담당자 변경 정보를 기록한다. |
| | | this.detectIssueManager(issue, issueForm, description); |
| | | // 사용자 정의 필드 변경 정보를 기록한다. |
| | | this.detectCustomField(issue, issueForm, description); |
| | | |
| | | // 이슈 제목 변경 정보를 기록한다. |
| | | if (!issue.getTitle().equals(issueForm.getTitle())) { |
| | | description.append("<li><span translate=\"common.updateTitle\">제목이 변경되었습니다.</span> </li>"); |
| | | } |
| | | |
| | | // 이슈 내용 변경 정보를 기록한다. |
| | | if (!issue.getDescription().equals(issueForm.getDescription())) { |
| | | description.append("<li><span translate=\"common.updateContent\">내용이 변경되었습니다.</span> </li>"); |
| | | } |
| | | |
| | | if (description.toString().length() > 1){ |
| | | StringBuilder firstEnd = new StringBuilder(); |
| | | firstEnd.append("<ul class=\"activity-list\">"); |
| | | firstEnd.append(description.toString()); |
| | | firstEnd.append("</ul>"); |
| | | return firstEnd; |
| | | } |
| | | |
| | | return description; |
| | | } |
| | | |
| | | // 이슈 프로젝트 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectProject(Issue issue, IssueForm issueForm, StringBuilder description, Project project) { |
| | | if (!issue.getProject().getId().equals(issueForm.getProjectId())) { |
| | | String title = "<span translate=\"common.updateProject\">프로젝트가 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, issue.getProject().getName(), project.getName()); |
| | | } |
| | | } |
| | | |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | private void makeIssueHistoryHtml(StringBuilder description, String title, String beforeValue, String afterValue) { |
| | | description.append("<li>"); |
| | | description.append(title); |
| | | description.append(" <span class=\"fc-purple\">"); |
| | | description.append(beforeValue); |
| | | description.append("</span>"); |
| | | description.append("<i class=\"os-icon os-icon-arrow-right fc-grey\"></i>"); |
| | | description.append("<span class=\"text-primary bold\">"); |
| | | description.append(afterValue); |
| | | description.append("</span>"); |
| | | description.append("</li>"); |
| | | } |
| | | |
| | | // 이슈 중요도 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectIssueSeverity(Issue issue, IssueForm issueForm, StringBuilder description, Severity severity) { |
| | | if (!issue.getSeverity().getId().equals(issueForm.getSeverityId())) { |
| | | String title = "<span translate=\"common.updateSeverity\">중요도가 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, issue.getSeverity().getName(), severity.getName()); |
| | | } |
| | | } |
| | | |
| | | // 이슈 우선순위 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectIssuePriority(Issue issue, IssueForm issueForm, StringBuilder description, Priority priority) { |
| | | if (!issue.getPriority().getId().equals(issueForm.getPriorityId())) { |
| | | String title = "<span translate=\"common.updatePriority\">우선순위가 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, issue.getPriority().getName(), priority.getName()); |
| | | } |
| | | } |
| | | |
| | | // 이슈 상태 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectIssueStatus(Issue issue, IssueForm issueForm, StringBuilder description, IssueStatus issueStatus) { |
| | | if (!issue.getIssueStatus().getId().equals(issueForm.getIssueStatusId())) { |
| | | String title = "<span translate=\"common.updateHasStatus\">상태가 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, issue.getIssueStatus().getName(), issueStatus.getName()); |
| | | |
| | | // 이슈 위험 관리에 상태 변경 정보를 업데이트한다. - 담당자 변경 |
| | | this.issueRiskService.modifyIssueRisk(issue, true, false, issueForm.getIssueStatusId()); |
| | | } |
| | | } |
| | | |
| | | // 예약 발생으로 이슈 상태 변경된 정보를 기록한다. |
| | | @Override |
| | | public void detectReservationIssueStatus(Issue issue, StringBuilder description, IssueStatus issueStatus) { |
| | | description.append("<ul class=\"activity-list\">"); |
| | | |
| | | String title = "<span translate=\"common.updateHasStatusReservation\">이슈 발생 예약일이 되어 상태가 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, issue.getIssueStatus().getName(), issueStatus.getName()); |
| | | |
| | | description.append("</ul>"); |
| | | } |
| | | |
| | | // 워크플로우에서 이슈 상태가 삭제되어 상태가 변경된 정보를 기록한다. |
| | | @Override |
| | | public void recordRemoveWorkflowToIssueStatus(String oldIssueStatusName, String newIssueStatusName, StringBuilder description) { |
| | | description.append("<ul class=\"activity-list\">"); |
| | | |
| | | String title = "<span translate=\"common.upddetectReservationIssueStatusateWorkflowNotExist\">변경된 워크플로우에서 상태가 존재하지 않아 이슈의 상태가 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, oldIssueStatusName, newIssueStatusName); |
| | | |
| | | description.append("</ul>"); |
| | | } |
| | | |
| | | // 이슈 타입 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectIssueType(Issue issue, IssueForm issueForm, StringBuilder description, IssueType issueType) { |
| | | if (!issue.getIssueType().getId().equals(issueForm.getIssueTypeId())) { |
| | | String title = "<span translate=\"common.updateIssueType\">이슈 타입이 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, issue.getIssueType().getName(), issueType.getName()); |
| | | } |
| | | } |
| | | |
| | | // 이슈 기간 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectIssuePeriod(Issue issue, IssueForm issueForm, StringBuilder description) { |
| | | // 기간 신규 설정 또는 기간 삭제시 |
| | | if ((issue.getStartDate() == null && issueForm.getStartDate() != null) || (issue.getStartDate() != null && issueForm.getStartDate() == null)) { |
| | | // 기간 변경 정보를 기록한다. |
| | | this.recodeChangeIssuePeriod(issue, issueForm, description); |
| | | } |
| | | |
| | | if (issue.getStartDate() != null && issueForm.getStartDate() != null) { |
| | | if (!issue.getStartDate().equals(issueForm.getStartDate()) || !issue.getCompleteDate().equals(issueForm.getCompleteDate())) { |
| | | // 기간 변경 정보를 기록한다. |
| | | this.recodeChangeIssuePeriod(issue, issueForm, description); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 기간 변경 정보를 기록한다. |
| | | private void recodeChangeIssuePeriod(Issue issue, IssueForm issueForm, StringBuilder description) { |
| | | String title = "<span translate=\"common.updatePeriod\">기간이 변경되었습니다.</span>"; |
| | | // 기간 정보를 기록한다. |
| | | String beforePeriod = this.recodeIssuePeriod(issue.getStartDate(), issue.getCompleteDate()); |
| | | String afterPeriod = this.recodeIssuePeriod(issueForm.getStartDate(), issueForm.getCompleteDate()); |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, beforePeriod, afterPeriod); |
| | | } |
| | | |
| | | // 기간 정보를 기록한다. |
| | | private String recodeIssuePeriod(String startDate, String completeDate) { |
| | | StringBuilder recodeIssuePeriod = new StringBuilder(); |
| | | |
| | | if (startDate != null) { |
| | | recodeIssuePeriod.append(startDate); |
| | | recodeIssuePeriod.append(" ~ "); |
| | | recodeIssuePeriod.append(completeDate); |
| | | } |
| | | else { |
| | | recodeIssuePeriod.append("<span translate=\"common.unspecified\">미지정</span>"); |
| | | } |
| | | |
| | | return recodeIssuePeriod.toString(); |
| | | } |
| | | |
| | | |
| | | // 연관 일감 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectRelationIssue(IssueHistoryType type, IssueRelation issueRelation, StringBuilder description) { |
| | | if (type == IssueHistoryType.ADD) { |
| | | description.append("<span translate=\"issue.relationIssueAddHistory\">연관 일감이 추가되었습니다. </span>"); |
| | | description.append("<span class=\"text-primary bold\"> > " + issueRelation.getRelationIssue().getTitle() + "</span>"); |
| | | } else { |
| | | description.append("<span translate=\"issue.relationIssueRemoveHistory\">연관 일감이 삭제되었습니다. " + issueRelation.getRelationIssue().getTitle() + "</span>"); |
| | | description.append("<span class=\"text-primary bold\"> > " + issueRelation.getRelationIssue().getTitle() + "</span>"); |
| | | } |
| | | } |
| | | |
| | | // 담당자 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectIssueManager(Issue issue, IssueForm issueForm, StringBuilder description) { |
| | | boolean saveIssueRisk = false; // 이슈 위험 관리에 이중 저장되는 것을 방지하기 위한 구분 값 |
| | | |
| | | // 담당자 수가 달려젔을 경우 |
| | | if (issue.getIssueUsers().size() != issueForm.getUserIds().size()) { |
| | | this.recodeIssueManager(issue, issueForm, description); |
| | | // 이슈 위험 관리에 담당자 변경 정보를 업데이트한다. - 담당자 변경 |
| | | this.issueRiskService.modifyIssueRisk(issue, false, true, null); |
| | | saveIssueRisk = true; |
| | | } |
| | | |
| | | // 담당자 수는 같으나 사용자가 달라졌을 경우 |
| | | if (issue.getIssueUsers().size() > 0 && issueForm.getUserIds().size() > 0) { |
| | | // 이전 담당자 표시 |
| | | for (IssueUser issueUser : issue.getIssueUsers()) { |
| | | boolean change = true; |
| | | User user = issueUser.getUser(); |
| | | |
| | | for (Long userId : issueForm.getUserIds()) { |
| | | if (user.getId().equals(userId)) { |
| | | change = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (change) { |
| | | // 담당자 변경 정보 기록 |
| | | this.recodeIssueManager(issue, issueForm, description); |
| | | // 담당자수가 달라졌을 경우에 저장되지 않았다면 여기서 이슈 위험 관리 저장을 한다. |
| | | if (!saveIssueRisk) { |
| | | // 이슈 위험 관리에 담당자 변경 정보를 업데이트한다. - 담당자 변경 |
| | | this.issueRiskService.modifyIssueRisk(issue, false, true, null); |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 담당자 변경 정보 기록 |
| | | private void recodeIssueManager(Issue issue, IssueForm issueForm, StringBuilder description) { |
| | | String title = "<span translate=\"common.updateAssignee\">담당자가 변경되었습니다.</span>"; |
| | | StringBuilder beforeUser = new StringBuilder(); |
| | | |
| | | // 이전 담당자 표시 |
| | | for (IssueUser issueUser : issue.getIssueUsers()) { |
| | | beforeUser.append(issueUser.getUser().getName()); |
| | | beforeUser.append(", "); |
| | | } |
| | | // 담당자가 없었으면 없음으로 표시 |
| | | if (issue.getIssueUsers().size() < 1) { |
| | | beforeUser.append("<span translate=\"common.none\">없음</span>"); |
| | | } |
| | | |
| | | StringBuilder afterUser = new StringBuilder(); |
| | | for (Long userId : issueForm.getUserIds()) { |
| | | User user = this.userService.getUser(userId); |
| | | afterUser.append(user.getName()); |
| | | afterUser.append(", "); |
| | | } |
| | | |
| | | // 담당자가 없었으면 없음으로 표시 |
| | | if (issueForm.getUserIds().size() < 1) { |
| | | afterUser.append("<span translate=\"common.none\">없음</span>"); |
| | | } |
| | | |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, beforeUser.toString(), afterUser.toString()); |
| | | } |
| | | |
| | | // 이슈에 첨부된 파일에 대해 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectAttachedFile(IssueForm issueForm, StringBuilder description, List<MultipartFile> files) { |
| | | // 삭제 대상이 있거나 새로 업로드 된 파일이 존재할 경우 변경 정보 기록 |
| | | if (issueForm.getRemoveFiles().size() > 0 && files.size() > 0) { |
| | | description.append("<li><span translate=\"common.updateAttachment\">첨부 파일이 변경되었습니다.</span> </li>"); |
| | | } |
| | | |
| | | // 삭제 대상이 있거나 새로 업로드 된 파일이 존재할 경우 변경 정보 기록 |
| | | if (issueForm.getRemoveFiles().size() > 0 && files.size() < 1) { |
| | | description.append("<li><span translate=\"common.deleteAttachment\">첨부 파일이 삭제되었습니다.</span> </li>"); |
| | | } |
| | | |
| | | // 삭제 대상이 있거나 새로 업로드 된 파일이 존재할 경우 변경 정보 기록 |
| | | if (issueForm.getRemoveFiles().size() < 1 && files.size() > 0) { |
| | | description.append("<li><span translate=\"common.registerAttachment\">첨부 파일이 등록되었습니다.</span> </li>"); |
| | | } |
| | | } |
| | | |
| | | // 이슈에서 사용되는 사용자 정의 필드 변경 정보를 기록한다. |
| | | @Override |
| | | public void detectCustomField(Issue issue, IssueForm issueForm, StringBuilder description) { |
| | | // 이슈 폼에서 올라온 사용자 정의 필드 변경 정보를 추출해서 객체로 만든다. |
| | | List<IssueCustomFieldValue> formIssueCustomFieldValues = this.getIssueCustomFieldValuesByIssueForm(issue, issueForm); |
| | | List<Long> passMultiSelectCustomFields = Lists.newArrayList(); |
| | | |
| | | for (IssueCustomFieldValue issueCustomFieldValue : formIssueCustomFieldValues) { |
| | | CustomField customField = issueCustomFieldValue.getCustomField(); |
| | | |
| | | switch (customField.getCustomFieldType()) { |
| | | case INPUT : |
| | | case SINGLE_SELECT : |
| | | boolean existIssueCustomFieldValue = false; |
| | | |
| | | for (IssueCustomFieldValue savedIssueCustomFieldValue : issue.getIssueCustomFieldValues()) { |
| | | if (customField.getId().equals(savedIssueCustomFieldValue.getCustomField().getId())) { |
| | | existIssueCustomFieldValue = true; |
| | | |
| | | if (!issueCustomFieldValue.getUseValue().equals(savedIssueCustomFieldValue.getUseValue())) { |
| | | // 기존에 있던 값을 변경한 경우 |
| | | this.recodeCustomFieldValue(savedIssueCustomFieldValue.getUseValue(), issueCustomFieldValue.getUseValue(), customField.getName(), description, customField.getCustomFieldType()); |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!existIssueCustomFieldValue) { |
| | | // 기존에 저장된 내역이 없으면서 신규로 저장한 값이 공백일 경우는 저장하지 않는다. |
| | | if (!StringUtils.isEmpty(issueCustomFieldValue.getUseValue())) { |
| | | // 신규로 값을 저장한 경우 |
| | | this.recodeCustomFieldValue("", issueCustomFieldValue.getUseValue(), customField.getName(), description, customField.getCustomFieldType()); |
| | | } |
| | | } |
| | | |
| | | break; |
| | | case MULTI_SELECT : |
| | | this.recodeCaseMultiSelect(customField, issue, formIssueCustomFieldValues, passMultiSelectCustomFields, description); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈 폼에서 올라온 사용자 정의 필드 변경 정보를 추출해서 객체로 만든다. |
| | | private List<IssueCustomFieldValue> getIssueCustomFieldValuesByIssueForm(Issue issue, IssueForm issueForm) { |
| | | List<IssueCustomFieldValue> formIssueCustomFieldValues = Lists.newArrayList(); |
| | | |
| | | // 변경하려는 사용자 정의 필드 값을 IssueCustomFieldValue 객체로 만든다. |
| | | for (Map<String, Object> map : issueForm.getIssueCustomFields()) { |
| | | Map<String, Object> result = new HashMap<>(); |
| | | // customFieldVo 에서 사용자 정의 필드와 이슈 유형에 연결된 사용자 정의 필드 정보를 가져온다. |
| | | this.issueCustomFieldValueService.getCustomFieldAndIssueTypeCustomField(map, issue, result); |
| | | CustomField customField = (CustomField)result.get("customField"); |
| | | IssueTypeCustomField issueTypeCustomField = (IssueTypeCustomField)result.get("issueTypeCustomField"); |
| | | List<String> useValues = MapUtil.getStrings(map, "useValues"); |
| | | |
| | | if (useValues != null) { |
| | | for (String useValue : useValues) { |
| | | IssueCustomFieldValue issueCustomFieldValue = new IssueCustomFieldValue(issue, customField, issueTypeCustomField, useValue); |
| | | formIssueCustomFieldValues.add(issueCustomFieldValue); |
| | | } |
| | | |
| | | // 이슈 수정에서 사용자 정의 필드를 선택하지 않았을 경우에는 useValue 값을 공백으로 해서 객체를 생성한다. |
| | | if (useValues.size() < 1) { |
| | | IssueCustomFieldValue issueCustomFieldValue = new IssueCustomFieldValue(issue, customField, issueTypeCustomField, ""); |
| | | formIssueCustomFieldValues.add(issueCustomFieldValue); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return formIssueCustomFieldValues; |
| | | } |
| | | |
| | | // 멀티 셀렉트 유형에 대해 변경 내역을 확인하고 기록한다. |
| | | private void recodeCaseMultiSelect(CustomField customField, Issue issue, List<IssueCustomFieldValue> formIssueCustomFieldValues, List<Long> passMultiSelectCustomFields, StringBuilder description) { |
| | | boolean passMultiSelect = false; |
| | | // 한번 체크한 멀티 셀렉트는 더 이상 변경 내역을 저장하지 않는다. (issue custom field value 에는 멀티셀렉트 값 마다 저장되어있어서...) |
| | | for (Long passMultiSelectCustomFieldId : passMultiSelectCustomFields) { |
| | | if (customField.getId().equals(passMultiSelectCustomFieldId)) { |
| | | passMultiSelect = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (passMultiSelect) { |
| | | return; |
| | | } |
| | | else { |
| | | passMultiSelectCustomFields.add(customField.getId()); |
| | | } |
| | | |
| | | // 폼에 있는 멀티 셀렉트 값 추출 - 해당 사용자 정의 필드에서 사용된 값 |
| | | List<String> formCustomFieldValues = this.getMultiSelectCustomFieldValues(customField, formIssueCustomFieldValues); |
| | | // 저장되어 있는 멀티 셀렉트 값을 추출 |
| | | List<String> savedCustomFieldValues = this.getMultiSelectCustomFieldValues(customField, Lists.newArrayList(issue.getIssueCustomFieldValues())); |
| | | |
| | | // 변경 정보 저장 |
| | | if (formCustomFieldValues.size() != savedCustomFieldValues.size()) { |
| | | this.recodeMultiSelectCustomFieldValue(savedCustomFieldValues, formCustomFieldValues, customField.getName(), description); |
| | | } |
| | | else { |
| | | for (String formCustomFieldValue : formCustomFieldValues) { |
| | | boolean checkValue = false; |
| | | |
| | | for (String savedCustomFieldValue : savedCustomFieldValues) { |
| | | if (formCustomFieldValue.equals(savedCustomFieldValue)) { |
| | | checkValue = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!checkValue) { |
| | | // 변경 정보 저장 |
| | | this.recodeMultiSelectCustomFieldValue(savedCustomFieldValues, formCustomFieldValues, customField.getName(), description); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 멀티 셀렉트에 있는 사용자 정의 필드 값을 추출한다. |
| | | private List<String> getMultiSelectCustomFieldValues(CustomField customField, List<IssueCustomFieldValue> issueCustomFieldValues) { |
| | | List<String> customFieldValues = Lists.newArrayList(); |
| | | |
| | | // 폼에 있는 멀티 셀렉트 값 추출 |
| | | for (IssueCustomFieldValue issueCustomFieldValue : issueCustomFieldValues) { |
| | | if (issueCustomFieldValue.getCustomField().getCustomFieldType().equals(CustomFieldType.MULTI_SELECT) && customField.getId().equals(issueCustomFieldValue.getCustomField().getId())) { |
| | | if (!StringUtils.isEmpty(issueCustomFieldValue.getUseValue())) { |
| | | customFieldValues.add(issueCustomFieldValue.getUseValue()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return customFieldValues; |
| | | } |
| | | |
| | | // 멀티 셀렉트의 변경된 값을 기록한다. |
| | | private void recodeMultiSelectCustomFieldValue(List<String> oldValues, List<String> newValues, String customFieldName, StringBuilder description) { |
| | | StringBuilder oldValueBuilder = new StringBuilder(); |
| | | StringBuilder newValueBuilder = new StringBuilder(); |
| | | // 배열에서 값을 추출한다. |
| | | this.setListValue(oldValues, oldValueBuilder); |
| | | // 배열에서 값을 추출한다. |
| | | this.setListValue(newValues, newValueBuilder); |
| | | // 사용자 정의 필드 변경 정보를 저장한다. |
| | | this.recodeCustomFieldValue(oldValueBuilder.toString(), newValueBuilder.toString(), customFieldName, description, CustomFieldType.MULTI_SELECT); |
| | | } |
| | | |
| | | // 배열에서 값을 추출한다. |
| | | private void setListValue(List<String> values, StringBuilder stringBuilder) { |
| | | for (String value : values) { |
| | | stringBuilder.append(value); |
| | | stringBuilder.append(", "); |
| | | } |
| | | } |
| | | |
| | | // 사용자 정의 필드 변경 정보를 저장한다. |
| | | private void recodeCustomFieldValue(String oldValue, String newValue, String customFieldName, StringBuilder description, CustomFieldType customFieldType) { |
| | | String title = "(" + customFieldName + ")<span translate=\"common.updateCustomField\">사용자 정의 필드가 변경되었습니다.</span>"; |
| | | // 기록에 남기는 사용자 정의 필드가 공백 값이면 알아볼 수 있게 알림을 넣어준다. |
| | | String beforeValue = this.checkEmptyCustomFieldValue(oldValue, customFieldType); |
| | | String afterValue = this.checkEmptyCustomFieldValue(newValue, customFieldType); |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, beforeValue, afterValue); |
| | | } |
| | | |
| | | // 기록에 남기는 사용자 정의 필드가 공백 값이면 알아볼 수 있게 알림을 넣어준다. |
| | | private String checkEmptyCustomFieldValue(String value, CustomFieldType customFieldType) { |
| | | String result = ""; |
| | | |
| | | if (StringUtils.isEmpty(value)) { |
| | | switch(customFieldType) { |
| | | case INPUT: |
| | | result = "<span translate=\"common.noValueEntered\">입력한 값이 없습니다.</span>"; |
| | | break; |
| | | case SINGLE_SELECT: |
| | | case MULTI_SELECT: |
| | | result = "<span translate=\"common.noValueSelected\">선택한 값이 없습니다.</span>"; |
| | | break; |
| | | } |
| | | } |
| | | else { |
| | | result = value; |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | // 사용자 정의 필드의 옵션 값이 삭제되어 이슈에서 사용된 값이 삭제될 경우 변경 정보를 저장한다. |
| | | @Override |
| | | @Transactional |
| | | public void recodeRemoveCustomFieldOptionValue(CustomField customField, String oldValue, String newValue, StringBuilder description) { |
| | | description.append("<ul class=\"activity-list\">"); |
| | | String title = "(" + customField.getName() + ")<span translate=\"common.updateIssueCustomField\">사용자 정의 필드 옵션 값이 변경되어 이슈의 사용자 정의 필드 값이 변경되었습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, oldValue, newValue); |
| | | |
| | | description.append("</ul>"); |
| | | } |
| | | |
| | | // 사용자 정의 필드 유형이 변경되어 이슈에서 사용된 옵션 값이 삭제되었다고 저장한다. |
| | | @Override |
| | | @Transactional |
| | | public void recodeChangeCustomFieldType(CustomField customField, String oldValue, StringBuilder description) { |
| | | description.append("<ul class=\"activity-list\">"); |
| | | |
| | | String title = "(" + customField.getName() + ")<span translate=\"common.updateIssueCustomFieldType\">사용자 정의 필드 유형이 변경되어 이슈의 사용자 정의 필드 값이 변경되었습니다.</span>"; |
| | | String newValue = "<span translate=\"common.noValueEntered\">입력한 값이 없습니다.</span>"; |
| | | // 이력 정보를 html 태그로 만들어 준다. |
| | | this.makeIssueHistoryHtml(description, title, oldValue, newValue); |
| | | |
| | | description.append("</ul>"); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.IssueNumberGenerator; |
| | | import kr.wisestone.owl.domain.Project; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.IssueNumberGeneratorRepository; |
| | | import kr.wisestone.owl.service.IssueNumberGeneratorService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueNumberGeneratorServiceImpl extends AbstractServiceImpl<IssueNumberGenerator, Long, JpaRepository<IssueNumberGenerator, Long>> implements IssueNumberGeneratorService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueNumberGeneratorServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueNumberGeneratorRepository issueNumberGeneratorRepository; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueNumberGenerator, Long> getRepository() { |
| | | return this.issueNumberGeneratorRepository; |
| | | } |
| | | |
| | | // 각 프로젝트의 이슈 번호를 자동으로 생성한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Long generateIssueNumber(Project project) { |
| | | IssueNumberGenerator issueNumberGenerator = this.issueNumberGeneratorRepository.findByProjectId(project.getId()); |
| | | |
| | | if (issueNumberGenerator == null) { |
| | | issueNumberGenerator = new IssueNumberGenerator(project, 0L); |
| | | } |
| | | else { |
| | | issueNumberGenerator.setNumber(issueNumberGenerator.getNumber() + 1); |
| | | } |
| | | |
| | | this.issueNumberGeneratorRepository.saveAndFlush(issueNumberGenerator); |
| | | |
| | | return issueNumberGenerator.getNumber(); |
| | | } |
| | | |
| | | // 이슈 엑셀 import 가 완료된 후 사용된 issue number 를 업데이트해준다. |
| | | @Override |
| | | @Transactional |
| | | public void updateIssueNumber(Map<Long, Long> issueNumberMaps) { |
| | | Iterator iterator = issueNumberMaps.keySet().iterator(); |
| | | |
| | | while(iterator.hasNext()) { |
| | | Long projectId = (Long)iterator.next(); |
| | | IssueNumberGenerator issueNumberGenerator = this.issueNumberGeneratorRepository.findByProjectId(projectId); |
| | | |
| | | if (issueNumberGenerator == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NUMBER_GENERATOR_NOT_EXIST)); |
| | | } |
| | | |
| | | Long issueNumber = issueNumberMaps.get(projectId); |
| | | |
| | | if (issueNumber == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NUMBER_NOT_EXIST)); |
| | | } |
| | | |
| | | issueNumberGenerator.setNumber(--issueNumber); |
| | | this.issueNumberGeneratorRepository.saveAndFlush(issueNumberGenerator); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueHistory; |
| | | import kr.wisestone.owl.domain.IssueRelation; |
| | | import kr.wisestone.owl.domain.enumType.IssueHistoryType; |
| | | import kr.wisestone.owl.repository.IssueRelationRepository; |
| | | import kr.wisestone.owl.service.IssueHistoryService; |
| | | import kr.wisestone.owl.service.IssueRelationService; |
| | | import kr.wisestone.owl.service.IssueService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.IssueRelationVo; |
| | | import kr.wisestone.owl.vo.IssueVo; |
| | | import kr.wisestone.owl.vo.ResPage; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueRelationCondition; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.transaction.Transactional; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueRelationServiceImpl extends AbstractServiceImpl<IssueRelation, Long, JpaRepository<IssueRelation, Long>> implements IssueRelationService { |
| | | |
| | | @Autowired |
| | | private IssueRelationRepository issueRelationRepository; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private IssueHistoryService issueHistoryService; |
| | | |
| | | @Override |
| | | protected IssueRelationRepository getRepository() { |
| | | return this.issueRelationRepository; |
| | | } |
| | | |
| | | // 연관 일감 추가 |
| | | @Override |
| | | public void addRelationIssue(Map<String, Object> resJsonData, IssueRelationCondition condition) { |
| | | if (condition != null) { |
| | | Issue issue = this.issueService.getIssue(condition.getIssueId()); |
| | | |
| | | IssueRelation issueRelation = new IssueRelation(); |
| | | issueRelation.setIssue(issue); |
| | | issueRelation.setRelationIssue(issueService.getIssue(condition.getRelationIssueId())); |
| | | issueRelation.setRelationIssueType(condition.getRelationIssueType()); |
| | | |
| | | issueRelationRepository.saveAndFlush(issueRelation); |
| | | |
| | | StringBuilder sb = new StringBuilder(); |
| | | issueHistoryService.detectRelationIssue(IssueHistoryType.ADD, issueRelation, sb); |
| | | issueHistoryService.addIssueHistory(issue, IssueHistoryType.MODIFY, sb.toString()); |
| | | } |
| | | } |
| | | |
| | | // 연관 일감 가져오기 |
| | | @Override |
| | | public List<IssueVo> findRelationIssue(Map<String, Object> resJsonData, IssueRelationCondition condition, Pageable pageable) { |
| | | List<IssueRelation> issueRelations = issueRelationRepository.findAllByIssueId(condition.getIssueId()); |
| | | List<IssueVo> issueVos = new ArrayList<>(); |
| | | |
| | | if (issueRelations != null) { |
| | | for (IssueRelation issueRelation : issueRelations) { |
| | | issueVos.add(ConvertUtil.copyProperties(issueRelation.getRelationIssue(), IssueVo.class)); |
| | | } |
| | | |
| | | int totalCount = issueVos.size(); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | 1, totalCount)); |
| | | } |
| | | |
| | | return issueVos; |
| | | } |
| | | |
| | | // 연관 일감 가져오기 |
| | | @Override |
| | | public List<IssueVo> findRelationIssue(Long issueId) { |
| | | List<IssueRelation> issueRelations = issueRelationRepository.findAllByIssueId(issueId); |
| | | List<IssueVo> issueVos = new ArrayList<>(); |
| | | |
| | | if (issueRelations != null) { |
| | | for (IssueRelation issueRelation : issueRelations) { |
| | | issueVos.add(ConvertUtil.copyProperties(issueRelation.getRelationIssue(), IssueVo.class)); |
| | | } |
| | | } |
| | | |
| | | return issueVos; |
| | | } |
| | | |
| | | // 연관 일감 삭제 |
| | | @Override |
| | | @Transactional |
| | | public boolean removeRelationIssue(Map<String, Object> resJsonData, IssueRelationCondition condition) { |
| | | Long id = condition.getId(); |
| | | if (id != null) { |
| | | IssueRelation issueRelation = findOne(id); |
| | | if (issueRelation != null) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | issueHistoryService.detectRelationIssue(IssueHistoryType.DELETE, issueRelation, sb); |
| | | issueHistoryService.addIssueHistory(issueRelation.getIssue(), IssueHistoryType.MODIFY, sb.toString()); |
| | | |
| | | this.issueRelationRepository.deleteById(id); |
| | | |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.ElasticSearchConstants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueReservation; |
| | | import kr.wisestone.owl.domain.enumType.IssueReservationType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.IssueReservationRepository; |
| | | import kr.wisestone.owl.service.IssueReservationService; |
| | | import kr.wisestone.owl.service.IssueService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.ElasticSearchUtil; |
| | | import kr.wisestone.owl.vo.IssueReservationVo; |
| | | import kr.wisestone.owl.web.condition.IssueReservationCondition; |
| | | import kr.wisestone.owl.web.form.IssueReservationForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueReservationServiceImpl extends AbstractServiceImpl<IssueReservation, Long, JpaRepository<IssueReservation, Long>> implements IssueReservationService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueReservationServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private IssueReservationRepository issueReservationRepository; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueReservation, Long> getRepository() { |
| | | return this.issueReservationRepository; |
| | | } |
| | | |
| | | // 이슈 발생 예약 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailIssueReservation(Map<String, Object> resJsonData, IssueReservationCondition issueReservationCondition) { |
| | | IssueReservationVo issueReservationVo = new IssueReservationVo(); |
| | | |
| | | if (issueReservationCondition.getIssueId() != null) { |
| | | Issue issue = this.issueService.getIssue(issueReservationCondition.getIssueId()); |
| | | IssueReservation issueReservation = issue.getIssueReservation(); |
| | | |
| | | if (issueReservation != null) { |
| | | issueReservationVo = ConvertUtil.copyProperties(issueReservation, IssueReservationVo.class, "issueReservationType"); |
| | | |
| | | if (issueReservation.getIssueReservationType() != null) { |
| | | issueReservationVo.setIssueReservationType(issueReservation.getIssueReservationType().toString()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueReservationVo); |
| | | } |
| | | |
| | | // 이슈 발생 이력 아이디로 이슈 발생 이력을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueReservation getIssueReservation(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_NOT_EXIST)); |
| | | } |
| | | |
| | | IssueReservation issueReservation = this.findOne(id); |
| | | |
| | | if (issueReservation == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_NOT_EXIST)); |
| | | } |
| | | |
| | | return issueReservation; |
| | | } |
| | | |
| | | // 이슈 발생 이력 정보를 수정한다. |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueReservation(Map<String, Object> resJsonData, IssueReservationForm issueReservationForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | IssueReservation issueReservation; |
| | | |
| | | // 수정 |
| | | if (issueReservationForm.getId() != null) { |
| | | issueReservation = this.getIssueReservation(issueReservationForm.getId()); |
| | | ConvertUtil.copyProperties(issueReservationForm, issueReservation, "id", "issueReservationType"); |
| | | |
| | | if (!StringUtils.isEmpty(issueReservationForm.getIssueReservationType())) { |
| | | issueReservation.setIssueReservationType(IssueReservationType.valueOf(issueReservationForm.getIssueReservationType())); |
| | | // 이슈 발생 예약일 체크 |
| | | this.verifyReservation(issueReservation.getIssueReservationType(), issueReservation.getReservation()); |
| | | } |
| | | else { |
| | | issueReservation.setIssueReservationType(null); |
| | | issueReservation.setReservation(null); |
| | | } |
| | | } |
| | | else { |
| | | Issue issue = this.issueService.getIssue(issueReservationForm.getIssueId()); |
| | | // 생성 |
| | | issueReservation = ConvertUtil.copyProperties(issueReservationForm, IssueReservation.class, "issueReservationType"); |
| | | issueReservation.setIssue(issue); |
| | | issueReservation.setWorkspace(issue.getProject().getWorkspace()); |
| | | |
| | | if (!StringUtils.isEmpty(issueReservationForm.getIssueReservationType())) { |
| | | issueReservation.setIssueReservationType(IssueReservationType.valueOf(issueReservationForm.getIssueReservationType())); |
| | | } |
| | | } |
| | | |
| | | this.issueReservationRepository.saveAndFlush(issueReservation); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, ConvertUtil.copyProperties(issueReservation, IssueReservationVo.class)); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_RESERVATION)); |
| | | } |
| | | |
| | | // 이슈 발생 예약일 체크 |
| | | private void verifyReservation(IssueReservationType issueReservationType, String reservation) { |
| | | switch (issueReservationType) { |
| | | case DAY: |
| | | if (!StringUtils.isEmpty(reservation)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | break; |
| | | case WEEK: |
| | | if (StringUtils.isEmpty(reservation)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | boolean pass = false; |
| | | |
| | | // 일 단위 예약 |
| | | switch (reservation) { |
| | | case "1": |
| | | case "2": |
| | | case "3": |
| | | case "4": |
| | | case "5": |
| | | case "6": |
| | | case "7": |
| | | pass = true; |
| | | break; |
| | | } |
| | | |
| | | if (!pass) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | break; |
| | | case MONTH: |
| | | if (StringUtils.isEmpty(reservation)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | if (!reservation.matches("^[0-9]*$")) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | if (Integer.parseInt(reservation) > 31) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | break; |
| | | case YEAR: |
| | | if (StringUtils.isEmpty(reservation)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | if (!reservation.matches("^[0-9]+-[0-9]+$")) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | String[] date = reservation.split("-"); |
| | | |
| | | if (date.length < 2) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | if (Integer.parseInt(date[0]) > 12 || Integer.parseInt(date[0]) < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | if (Integer.parseInt(date[1]) > 31 || Integer.parseInt(date[1]) < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | |
| | | switch (Integer.parseInt(date[0])) { |
| | | case 2: |
| | | if (Integer.parseInt(date[1]) > 29) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | break; |
| | | case 4: |
| | | case 6: |
| | | case 9: |
| | | case 11: |
| | | if (Integer.parseInt(date[1]) > 30) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_RESERVATION_VALUE_INVALID)); |
| | | } |
| | | break; |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 이슈 발생 이력 정보가 저장되어 있는 항목을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueReservation> findByIssueReservationTypeNotNull() { |
| | | return this.issueReservationRepository.findByIssueReservationTypeNotNull(); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueRisk; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.repository.IssueRiskRepository; |
| | | import kr.wisestone.owl.service.IssueRiskService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueRiskServiceImpl extends AbstractServiceImpl<IssueRisk, Long, JpaRepository<IssueRisk, Long>> implements IssueRiskService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueRiskServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueRiskRepository issueRiskRepository; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueRisk, Long> getRepository() { |
| | | return this.issueRiskRepository; |
| | | } |
| | | |
| | | // 이슈가 생성될 때 이슈 위험 관리도 같이 생성된다. |
| | | @Override |
| | | @Transactional |
| | | public IssueRisk addIssueRisk(Issue issue, Workspace workspace) { |
| | | IssueRisk issueRisk = new IssueRisk(); |
| | | issueRisk.setChangeIssueStatusCount(0L); |
| | | issueRisk.setChangeAssigneeCount(0L); |
| | | issueRisk.setIssue(issue); |
| | | issueRisk.setWorkspace(workspace); |
| | | issueRisk.setIssueStatusIds(issue.getIssueStatus().getId().toString()); |
| | | return this.issueRiskRepository.saveAndFlush(issueRisk); |
| | | } |
| | | |
| | | // 이슈에서 담당자나 상태가 변경될 경우 이슈 위험 관리 정보를 업데이트한다. |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueRisk(Issue issue, Boolean changeIssueStatus, Boolean changeAssignee, Long issueStatusId) { |
| | | IssueRisk issueRisk = issue.getIssueRisk(); |
| | | |
| | | // 상태 변경 |
| | | if (changeIssueStatus) { |
| | | String issueStatusIds = issueRisk.getIssueStatusIds(); |
| | | issueStatusIds += "&" + issueStatusId; |
| | | |
| | | Map<String, Integer> issueStatusIdMaps = new HashMap<>(); |
| | | |
| | | for (String key : issueStatusIds.split("&")) { |
| | | if (!issueStatusIdMaps.containsKey(key)) { |
| | | issueStatusIdMaps.put(key, 1); |
| | | } |
| | | else { |
| | | issueStatusIdMaps.put(key, issueStatusIdMaps.get(key) + 1); |
| | | } |
| | | } |
| | | |
| | | Integer saveCount = 0; |
| | | |
| | | for (Integer value : issueStatusIdMaps.values()) { |
| | | if (value > saveCount) { |
| | | saveCount = value; |
| | | } |
| | | } |
| | | |
| | | issueRisk.setChangeIssueStatusCount(saveCount.longValue()); |
| | | issueRisk.setIssueStatusIds(issueStatusIds); |
| | | } |
| | | |
| | | // 담당자 변경 |
| | | if (changeAssignee) { |
| | | issueRisk.setChangeAssigneeCount(issueRisk.getChangeAssigneeCount() + 1); |
| | | } |
| | | |
| | | this.issueRiskRepository.saveAndFlush(issueRisk); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.domain.IssueSearch; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.repository.IssueSearchRepository; |
| | | import kr.wisestone.owl.service.IssueSearchService; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueSearchServiceImpl extends AbstractServiceImpl<IssueSearch, Long, JpaRepository<IssueSearch, Long>> implements IssueSearchService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueSearchServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueSearchRepository issueSearchRepository; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueSearch, Long> getRepository() { |
| | | return this.issueSearchRepository; |
| | | } |
| | | |
| | | // 이슈 검색 조건을 저장한다. - 이슈 번호만 저장한다. |
| | | @Override |
| | | @Transactional |
| | | public IssueSearch addIssueSearch(Map<String, Object> params) { |
| | | String conditions = MapUtil.getString(params, "conditions"); |
| | | // 해당 업무 공간에서 사용자의 이슈 검색 조건을 조회한다. |
| | | IssueSearch saveIssueSearch = this.findByUserIdAndWorkspaceId(); |
| | | |
| | | if (saveIssueSearch == null) { |
| | | IssueSearch issueSearch = new IssueSearch(); |
| | | Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | User user = this.userService.getUser(this.webAppUtil.getLoginId()); |
| | | issueSearch.setWorkspace(workspace); |
| | | issueSearch.setUser(user); |
| | | issueSearch.setConditions(conditions); |
| | | return this.issueSearchRepository.saveAndFlush(issueSearch); |
| | | } |
| | | else { |
| | | saveIssueSearch.setConditions(conditions); |
| | | return this.issueSearchRepository.saveAndFlush(saveIssueSearch); |
| | | } |
| | | } |
| | | |
| | | // 해당 업무 공간에서 사용자의 이슈 검색 조건을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueSearch findByUserIdAndWorkspaceId() { |
| | | return this.issueSearchRepository.findByUserIdAndWorkspaceId(this.webAppUtil.getLoginId(), |
| | | this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | |
| | | // 저장된 이슈 검색 조건을 조회 후 즉시 삭제한다 - 이슈 번호만 검색 조건 저장해서 사용 |
| | | @Override |
| | | @Transactional |
| | | public void detailIssueSearch(Map<String, Object> resJsonData) { |
| | | // 해당 업무 공간에서 사용자의 이슈 검색 조건을 조회한다. |
| | | IssueSearch issueSearch = this.findByUserIdAndWorkspaceId(); |
| | | |
| | | if (issueSearch != null) { |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueSearch.getConditions()); |
| | | issueSearch.setConditions(null); |
| | | this.issueSearchRepository.saveAndFlush(issueSearch); |
| | | } |
| | | else { |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, ""); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.common.ExcelConditionCheck; |
| | | import kr.wisestone.owl.config.CommonConfiguration; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.ElasticSearchConstants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.domain.enumType.EmailType; |
| | | import kr.wisestone.owl.domain.enumType.IssueHistoryType; |
| | | import kr.wisestone.owl.domain.enumType.IssueStatusType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.IssueMapper; |
| | | import kr.wisestone.owl.mapper.ProjectMapper; |
| | | import kr.wisestone.owl.repository.IssueRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.*; |
| | | import kr.wisestone.owl.util.DateUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueTypeCustomFieldCondition; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.IssueCommentForm; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.commons.lang3.time.StopWatch; |
| | | import org.apache.poi.ss.usermodel.*; |
| | | import org.jsoup.Jsoup; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.messaging.simp.SimpMessagingTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | import java.util.concurrent.locks.Condition; |
| | | |
| | | @Service |
| | | public class IssueServiceImpl extends AbstractServiceImpl<Issue, Long, JpaRepository<Issue, Long>> implements IssueService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueRepository issueRepository; |
| | | |
| | | @Autowired |
| | | private ProjectService projectService; |
| | | |
| | | @Autowired |
| | | private IssueStatusService issueStatusService; |
| | | |
| | | @Autowired |
| | | private IssueTypeService issueTypeService; |
| | | |
| | | @Autowired |
| | | private PriorityService priorityService; |
| | | |
| | | @Autowired |
| | | private SeverityService severityService; |
| | | |
| | | @Autowired |
| | | private CommonConfiguration configuration; |
| | | |
| | | @Autowired |
| | | private IssueNumberGeneratorService issueNumberGeneratorService; |
| | | |
| | | @Autowired |
| | | private AttachedFileService attachedFileService; |
| | | |
| | | @Autowired |
| | | private IssueCustomFieldValueService issueCustomFieldValueService; |
| | | |
| | | @Autowired |
| | | private IssueUserService issueUserService; |
| | | |
| | | @Autowired |
| | | private CustomFieldService customFieldService; |
| | | |
| | | @Autowired |
| | | private IssueTypeCustomFieldService issueTypeCustomFieldService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private IssueCommentService issueCommentService; |
| | | |
| | | @Autowired |
| | | private IssueHistoryService issueHistoryService; |
| | | |
| | | @Autowired |
| | | private ProjectRoleUserService projectRoleUserService; |
| | | |
| | | @Autowired |
| | | private IssueRiskService issueRiskService; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private SystemEmailService systemEmailService; |
| | | |
| | | @Autowired |
| | | private IssueVersionService issueVersionService; |
| | | |
| | | @Autowired |
| | | private IssueReservationService issueReservationService; |
| | | |
| | | @Autowired |
| | | private UserWorkspaceService userWorkspaceService; |
| | | |
| | | @Autowired |
| | | private IssueRelationService issueRelationService; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | @Autowired |
| | | private IssueMapper issueMapper; |
| | | |
| | | @Autowired |
| | | private ExcelConditionCheck excelConditionCheck; |
| | | |
| | | @Autowired |
| | | private SimpMessagingTemplate simpMessagingTemplate; |
| | | |
| | | @Override |
| | | protected JpaRepository<Issue, Long> getRepository() { |
| | | return this.issueRepository; |
| | | } |
| | | |
| | | private static final int EXCEL_DOWNLOAD_MAX_ROWS = 10000; // excel download 제한 |
| | | private static final int EXCEL_IMPORT_MAX_ROWS = 10000; // excel import 제한 |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void addIssueVersion(Long id) { |
| | | Issue issue = this.getIssue(id); |
| | | // 이슈 버전 생성 |
| | | this.issueVersionService.addIssueVersion(issue); |
| | | } |
| | | |
| | | |
| | | // 이슈를 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public Issue addIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 프로젝트 유효성 체크 |
| | | Project project = this.projectService.getProject(issueForm.getProjectId()); |
| | | // 이슈 유형 유효성 체크 |
| | | IssueType issueType = this.issueTypeService.getIssueType(issueForm.getIssueTypeId()); |
| | | // 우선순위 유효성 체크 |
| | | Priority priority = this.priorityService.getPriority(issueForm.getPriorityId()); |
| | | // 중요도 유효성 체크 |
| | | Severity severity = this.severityService.getSeverity(issueForm.getSeverityId()); |
| | | |
| | | // 제목 유효성 체크 |
| | | this.verifyTitle(issueForm.getTitle()); |
| | | // 날짜 유효성 체크 |
| | | this.checkStartCompleteDate(issueForm.getStartDate(), issueForm.getCompleteDate()); |
| | | |
| | | // 이슈 상태 유형이 '대기' 인 이슈 상태 가져오기 |
| | | IssueStatus issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow()); |
| | | |
| | | Issue issue = ConvertUtil.copyProperties(issueForm, Issue.class); |
| | | issue.setProject(project); |
| | | issue.setIssueStatus(issueStatus); |
| | | issue.setIssueType(issueType); |
| | | issue.setPriority(priority); |
| | | issue.setSeverity(severity); |
| | | issue.setIssueNumber(this.issueNumberGeneratorService.generateIssueNumber(project)); // 각 프로젝트의 고유 이슈 번호 생성 |
| | | |
| | | this.issueRepository.saveAndFlush(issue); |
| | | |
| | | issue.setReverseIndex(issue.getId() * -1); // 쿼리 속도 개선을 위해 리버스 인덱스 생성 |
| | | // 담당자 지정 |
| | | this.issueUserService.modifyIssueUser(issue, project.getWorkspace(), issueForm.getUserIds()); |
| | | |
| | | // multipartFile 을 file Map List 객체로 변경한다. |
| | | List<Map<String, Object>> convertFileMaps = this.convertMultipartFileToFile(multipartFiles); |
| | | // 첨부 파일 저장 |
| | | this.attachedFileService.addAttachedFile(convertFileMaps, issue, this.webAppUtil.getLoginUser().getAccount()); |
| | | // 텍스트 에디터에 첨부한 파일을 이슈와 연결 |
| | | this.checkNotHaveIssueIdAttachedFile(issue, issueForm); |
| | | // 사용자 정의 필드 저장 |
| | | this.issueCustomFieldValueService.modifyIssueCustomFieldValue(issue, issueForm.getIssueCustomFields()); |
| | | // 이슈 이력 생성 |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.ADD, null); |
| | | // 이슈 위험 관리 생성 |
| | | this.issueRiskService.addIssueRisk(issue, project.getWorkspace()); |
| | | // 영속성 컨텍스트 비우기 |
| | | this.clear(); |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | this.reservationIssueEmail(issue.getId(), EmailType.ISSUE_ADD); |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_ADD)); |
| | | |
| | | return issue; |
| | | } |
| | | |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | private void reservationIssueEmail(Long id, EmailType emailType) { |
| | | Issue issue = this.getIssue(id); |
| | | |
| | | Map<String, Object> issueMap = new HashMap<>(); |
| | | // 이슈 정보를 이메일 전송에 사용하기 위해 Map 형태로 변환한다. |
| | | this.makeIssueMapToIssue(issue, issueMap); |
| | | |
| | | Map<String, Object> projectRoleUserMap = new HashMap<>(); |
| | | projectRoleUserMap.put("id", issue.getProject().getId()); |
| | | projectRoleUserMap.put("statuses", Lists.newArrayList("02")); // 관리자 조회 |
| | | // 관리자 정보 셋팅 |
| | | List<Map<String, Object>> projectRoleUsers = this.projectRoleUserService.findProjectRoleUser(projectRoleUserMap); |
| | | |
| | | if (projectRoleUsers != null && !projectRoleUsers.isEmpty()) { |
| | | for (Map<String, Object> projectRoleUser : projectRoleUsers) { |
| | | UserVo userVo = ConvertUtil.convertMapToClass(projectRoleUser, UserVo.class); |
| | | |
| | | // 이슈 생성 알림 메일 전송 |
| | | this.systemEmailService.reservationEmail(new String[]{userVo.getAccount()}, emailType, issueMap); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈 정보를 이메일 전송에 사용하기 위해 Map 형태로 변환한다. |
| | | private void makeIssueMapToIssue(Issue issue, Map<String, Object> issueMap) { |
| | | issueMap.put("title", issue.getTitle()); |
| | | issueMap.put("issueNumber", issue.getIssueNumber()); |
| | | issueMap.put("issueTypeName", issue.getIssueType().getName()); |
| | | issueMap.put("issueStatusName", issue.getIssueStatus().getName()); |
| | | |
| | | // 담당자 |
| | | StringBuilder assigneeBuilder = new StringBuilder(); |
| | | for (IssueUser issueUser : issue.getIssueUsers()) { |
| | | assigneeBuilder.append(issueUser.getUser().getName()); |
| | | assigneeBuilder.append("("); |
| | | assigneeBuilder.append(CommonUtil.decryptAES128(issueUser.getUser().getAccount())); |
| | | assigneeBuilder.append(")"); |
| | | assigneeBuilder.append("\n"); |
| | | } |
| | | |
| | | issueMap.put("assignees", assigneeBuilder.toString()); |
| | | // 기간 |
| | | if (!StringUtils.isEmpty(issue.getStartDate())) { |
| | | issueMap.put("period", issue.getStartDate() + " ~ " + issue.getCompleteDate()); |
| | | } |
| | | |
| | | issueMap.put("severityName", issue.getSeverity().getName()); |
| | | issueMap.put("priorityName", issue.getPriority().getName()); |
| | | issueMap.put("projectName", issue.getProject().getName()); |
| | | issueMap.put("projectKey", issue.getProject().getProjectKey()); |
| | | |
| | | User user = this.userService.getUser(issue.getRegisterId()); |
| | | StringBuilder registerBuilder = new StringBuilder(); |
| | | registerBuilder.append(user.getName()); |
| | | registerBuilder.append("("); |
| | | registerBuilder.append(CommonUtil.decryptAES128(user.getAccount())); |
| | | registerBuilder.append(")"); |
| | | issueMap.put("register", registerBuilder.toString()); |
| | | |
| | | Map<String, Object> customField = new HashMap<>(); |
| | | |
| | | List<IssueCustomFieldValueVo> issueCustomFieldValueVos = this.issueCustomFieldValueService.findByIssueId(issue.getId()); |
| | | |
| | | for (IssueCustomFieldValueVo issueCustomFieldValueVo : issueCustomFieldValueVos) { |
| | | // 이미 데이터가 존재 |
| | | if (customField.get(issueCustomFieldValueVo.getCustomFieldVo().getName()) != null) { |
| | | List<String> useValues = (List<String>) customField.get(issueCustomFieldValueVo.getCustomFieldVo().getName()); |
| | | useValues.add(issueCustomFieldValueVo.getUseValue()); |
| | | customField.put(issueCustomFieldValueVo.getCustomFieldVo().getName(), useValues); |
| | | } else { |
| | | if (issueCustomFieldValueVo.getCustomFieldVo().getCustomFieldType().equals(CustomFieldType.INPUT.toString())) { |
| | | customField.put(issueCustomFieldValueVo.getCustomFieldVo().getName(), issueCustomFieldValueVo.getUseValue()); |
| | | } else { |
| | | customField.put(issueCustomFieldValueVo.getCustomFieldVo().getName(), Lists.newArrayList(issueCustomFieldValueVo.getUseValue())); |
| | | } |
| | | } |
| | | } |
| | | |
| | | List<Map<String, Object>> customFields = Lists.newArrayList(); |
| | | |
| | | Iterator<String> iterator = customField.keySet().iterator(); |
| | | while (iterator.hasNext()) { |
| | | String key = iterator.next(); |
| | | Map<String, Object> result = new HashMap<>(); |
| | | result.put("name", key); |
| | | result.put("useValue", customField.get(key)); |
| | | customFields.add(result); |
| | | } |
| | | |
| | | issueMap.put("customFields", customFields); |
| | | issueMap.put("description", issue.getDescription()); |
| | | |
| | | StringBuilder attachedFileBuilder = new StringBuilder(); |
| | | |
| | | List<AttachedFile> attachedFiles = this.attachedFileService.findByIssueId(issue.getId()); |
| | | |
| | | for (AttachedFile attachedFile : attachedFiles) { |
| | | attachedFileBuilder.append("<a href='"); |
| | | attachedFileBuilder.append(attachedFile.getPath()); |
| | | attachedFileBuilder.append("'>"); |
| | | attachedFileBuilder.append(attachedFile.getName()); |
| | | attachedFileBuilder.append("</a>"); |
| | | attachedFileBuilder.append("\n"); |
| | | } |
| | | |
| | | issueMap.put("attachedFiles", attachedFileBuilder.toString()); |
| | | } |
| | | |
| | | // 제목 유효성 체크 |
| | | private void verifyTitle(String title) { |
| | | if (StringUtils.isEmpty(title)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NO_TITLE)); |
| | | } |
| | | |
| | | if (title.length() > 300) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TITLE_MAX_LENGTH_OUT)); |
| | | } |
| | | } |
| | | |
| | | // 날짜 유효성 체크 |
| | | private void checkStartCompleteDate(String startDate, String completeDate) { |
| | | if (!StringUtils.isEmpty(startDate) && !StringUtils.isEmpty(completeDate)) { |
| | | Date start = DateUtil.convertStrToDate(startDate, "yy-MM-dd"); |
| | | Date end = DateUtil.convertStrToDate(completeDate, "yy-MM-dd"); |
| | | if (start.getTime() > end.getTime()) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.DATE_PICKER_NOT_AVAILABLE)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 텍스트 에디터에 첨부한 파일을 이슈와 연결 |
| | | private void checkNotHaveIssueIdAttachedFile(Issue issue, IssueForm issueForm) { |
| | | if (!issueForm.getAttachedFileIds().isEmpty()) { |
| | | this.attachedFileService.connectIssueIdAttachedFile(issue, issueForm); |
| | | } |
| | | } |
| | | |
| | | // 이슈 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | IssueCondition issueCondition, Pageable pageable) { |
| | | |
| | | // 검색 조건을 만든다 |
| | | if (!this.makeIssueSearchCondition(issueCondition, Lists.newArrayList("01", "02", "03"), pageable)) { |
| | | // 이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다. |
| | | this.notFoundIssueList(resJsonData, pageable); |
| | | return Lists.newArrayList(); |
| | | } |
| | | |
| | | Set<String> issueIds = new HashSet<>(); // 사용자 정의 필드 검색시 나오는 이슈 아이디 저장 컬렉션 |
| | | |
| | | // 사용자 정의 필드를 사용한 이슈를 찾는다. 만약 이슈가 없다면 여기서 이슈 조회가 끝난다. |
| | | if (!this.searchUseCustomFields(issueCondition, issueIds, resJsonData, pageable)) { |
| | | // 이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다. |
| | | this.notFoundIssueList(resJsonData, pageable); |
| | | return Lists.newArrayList(); |
| | | } |
| | | |
| | | // 튜닝 전 - 1.3 / 1.2 / 1.1 |
| | | // 튜닝 후 (단일/다중 검색 조건 3개 기준) - 0.49 / 0.41 / 0.47 / 0.41 |
| | | |
| | | List<IssueVo> issueVos = Lists.newArrayList(); // 이슈 목록 데이터 저장 컬렉션 |
| | | // 사용자 정의 필드로 검색한 이슈 아이디 값 |
| | | List<String> issueKeys = Lists.newArrayList(issueIds); |
| | | issueCondition.setIssueIds(issueKeys); |
| | | |
| | | List<Map<String, Object>> results = this.issueMapper.find(issueCondition); |
| | | // 튜닝 전 - 0.8, 0.9, 0.9, 0.9, 0.9 |
| | | StopWatch serviceStart = new StopWatch(); |
| | | serviceStart.start(); |
| | | Long totalCount = this.issueMapper.count(issueCondition); |
| | | // 튜닝 전 - 1.1, 1.1, 1.3, 1.2 |
| | | |
| | | serviceStart.stop(); |
| | | log.debug("serviceENd1 : " + serviceStart.getTime()); |
| | | |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | // 이슈 아이디 초기화 |
| | | issueCondition.setIssueIds(Lists.newArrayList()); |
| | | // Map 에 있는 데이터를 IssueVo 데이터로 변환한다. |
| | | this.setMapToIssueVo(results, issueVos, issueCondition); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_FIND)); |
| | | return issueVos; |
| | | } |
| | | |
| | | // 이슈 목록을 조회한다(차트용 - 연관일감포함) |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueVo> findChartIssue(Map<String, Object> resJsonData, |
| | | IssueCondition issueCondition, Pageable pageable) { |
| | | |
| | | // 검색 조건을 만든다 |
| | | if (!this.makeIssueSearchCondition(issueCondition,Lists.newArrayList("01", "02", "03"), pageable)) { |
| | | // 이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다. |
| | | this.notFoundIssueList(resJsonData, pageable); |
| | | return Lists.newArrayList(); |
| | | } |
| | | |
| | | Set<String> issueIds = new HashSet<>(); // 사용자 정의 필드 검색시 나오는 이슈 아이디 저장 컬렉션 |
| | | |
| | | // 사용자 정의 필드를 사용한 이슈를 찾는다. 만약 이슈가 없다면 여기서 이슈 조회가 끝난다. |
| | | if (!this.searchUseCustomFields(issueCondition, issueIds, resJsonData, pageable)) { |
| | | // 이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다. |
| | | this.notFoundIssueList(resJsonData, pageable); |
| | | return Lists.newArrayList(); |
| | | } |
| | | |
| | | // 튜닝 전 - 1.3 / 1.2 / 1.1 |
| | | // 튜닝 후 (단일/다중 검색 조건 3개 기준) - 0.49 / 0.41 / 0.47 / 0.41 |
| | | List<IssueVo> issueVos = Lists.newArrayList(); // 이슈 목록 데이터 저장 컬렉션 |
| | | // 사용자 정의 필드로 검색한 이슈 아이디 값 |
| | | List<String> issueKeys = Lists.newArrayList(issueIds); |
| | | issueCondition.setIssueIds(issueKeys); |
| | | |
| | | List<Map<String, Object>> results = this.issueMapper.find(issueCondition); |
| | | int totalCount = results.size(); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | |
| | | // 이슈 아이디 초기화 |
| | | issueCondition.setIssueIds(Lists.newArrayList()); |
| | | // Map 에 있는 데이터를 IssueVo 데이터로 변환한다. |
| | | this.setMapToIssueVoForChart(results, issueVos, issueCondition); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_FIND)); |
| | | return issueVos; |
| | | } |
| | | |
| | | // 이슈 목록을 조회한다(차트용 - 연관일감) |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueVo> findChartIssue(Map<String, Object> resJsonData, |
| | | ProjectCondition projectCondition, Pageable pageable) { |
| | | |
| | | IssueCondition issueCondition = new IssueCondition(); |
| | | // 검색 조건을 만든다 |
| | | if (!this.makeIssueSearchCondition(issueCondition, projectCondition, pageable)) { |
| | | // 이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다. |
| | | this.notFoundIssueList(resJsonData, pageable); |
| | | return Lists.newArrayList(); |
| | | } |
| | | |
| | | Set<String> issueIds = new HashSet<>(); // 사용자 정의 필드 검색시 나오는 이슈 아이디 저장 컬렉션 |
| | | List<IssueVo> issueVos = Lists.newArrayList(); // 이슈 목록 데이터 저장 컬렉션 |
| | | // 사용자 정의 필드로 검색한 이슈 아이디 값 |
| | | List<String> issueKeys = Lists.newArrayList(issueIds); |
| | | issueCondition.setIssueIds(issueKeys); |
| | | |
| | | List<Map<String, Object>> results = this.issueMapper.find(issueCondition); |
| | | int totalCount = results.size(); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | |
| | | // 이슈 아이디 초기화 |
| | | issueCondition.setIssueIds(Lists.newArrayList()); |
| | | // Map 에 있는 데이터를 IssueVo 데이터로 변환한다. |
| | | this.setMapToIssueVoForChart(results, issueVos, issueCondition); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_FIND)); |
| | | return issueVos; |
| | | } |
| | | |
| | | // Map 에 있는 데이터를 IssueVo 데이터로 변환한다. 차트용 |
| | | private void setMapToIssueVoForChart(List<Map<String, Object>> results, List<IssueVo> issueVos, IssueCondition issueCondition) { |
| | | for (Map<String, Object> result : results) { |
| | | IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class); |
| | | issueVos.add(issueVo); |
| | | issueCondition.addIssueIds(String.valueOf(issueVo.getId())); |
| | | } |
| | | |
| | | for (IssueVo issueVo : issueVos) { |
| | | this.setRelationIssue(issueVo, issueVo.getId()); |
| | | } |
| | | } |
| | | |
| | | // Map 에 있는 데이터를 IssueVo 데이터로 변환한다. |
| | | private void setMapToIssueVo(List<Map<String, Object>> results, List<IssueVo> issueVos, IssueCondition issueCondition) { |
| | | for (Map<String, Object> result : results) { |
| | | IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class); |
| | | issueVos.add(issueVo); |
| | | issueCondition.addIssueIds(String.valueOf(issueVo.getId())); |
| | | } |
| | | |
| | | // 이슈 사용자 정보 추가 |
| | | this.setIssueUserList(issueVos, issueCondition); |
| | | // 등록자 정보 추가 |
| | | this.setRegister(issueVos); // 담당자 정보 셋팅 |
| | | |
| | | // 사용자 정의 필드 정보 추가 |
| | | this.setIssueCustomFieldValue(issueVos, issueCondition); |
| | | } |
| | | |
| | | // 검색 조건을 만든다 |
| | | private boolean makeIssueSearchCondition(IssueCondition condition, List<String> projectStatues, Pageable pageable) { |
| | | if (pageable != null) { |
| | | condition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | condition.setPageSize(pageable.getPageSize()); |
| | | } |
| | | |
| | | condition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | |
| | | // 프로젝트 키가 존재할 경우 프로젝트 키에 해당하는 프로젝트를 조회하고 검색 조건에 셋팅한다. |
| | | if (!this.getProjectByProjectKey(condition.getProjectKey(), condition)) { |
| | | return false; |
| | | } |
| | | |
| | | // 프로젝트를 선택하지 않았으면 해당 업무 공간에서 참여하고 있는 프로젝트를 찾는다. |
| | | if (condition.getProjectIds().size() < 1) { |
| | | List<Map<String, Object>> projects = this.projectService.findByWorkspaceIdAndIncludeProjectAll(projectStatues, condition.getProjectType()); |
| | | List<Long> projectIds = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> result : projects) { |
| | | Long projectId = MapUtil.getLong(result, "id"); |
| | | |
| | | if (projectId != null) { |
| | | projectIds.add(projectId); |
| | | } |
| | | } |
| | | |
| | | condition.setProjectIds(projectIds); |
| | | |
| | | if (projectIds.size() < 1) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // 검색 조건을 만든다 |
| | | private boolean makeIssueSearchCondition(IssueCondition condition, ProjectCondition projectCondition, Pageable pageable) { |
| | | if (pageable != null) { |
| | | condition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | condition.setPageSize(pageable.getPageSize()); |
| | | } |
| | | |
| | | condition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | projectCondition.setWorkspaceId(condition.getWorkspaceId()); |
| | | |
| | | // 프로젝트 키가 존재할 경우 프로젝트 키에 해당하는 프로젝트를 조회하고 검색 조건에 셋팅한다. |
| | | if (!this.getProjectByProjectKey(condition.getProjectKey(), condition)) { |
| | | return false; |
| | | } |
| | | |
| | | // 프로젝트를 선택하지 않았으면 해당 업무 공간에서 참여하고 있는 프로젝트를 찾는다. |
| | | if (condition.getProjectIds().size() < 1) { |
| | | List<Map<String, Object>> projects = null; |
| | | if (this.userWorkspaceService.checkWorkspaceManager()) { |
| | | projects = this.projectMapper.findByWorkspaceManagerAll(projectCondition); |
| | | } else { |
| | | projects = this.projectService.findByWorkspaceIdAndIncludeProjectAll(projectCondition); |
| | | } |
| | | List<Long> projectIds = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> result : projects) { |
| | | Long projectId = MapUtil.getLong(result, "id"); |
| | | |
| | | if (projectId != null) { |
| | | projectIds.add(projectId); |
| | | } |
| | | } |
| | | |
| | | condition.setProjectIds(projectIds); |
| | | |
| | | if (projectIds.size() < 1) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // 프로젝트 키가 존재할 경우 프로젝트 키에 해당하는 프로젝트를 조회하고 검색 조건에 셋팅한다. |
| | | private boolean getProjectByProjectKey(String projectKey, IssueCondition condition) { |
| | | if (!StringUtils.isEmpty(projectKey)) { |
| | | Project project = this.projectService.findByProjectKey(projectKey); |
| | | |
| | | if (project != null) { |
| | | // 이미 프로젝트를 선택했을 경우에 프로젝트키로 검색한 프로젝트가 포함되어 있지 않으면 false |
| | | if (condition.getProjectIds().size() > 0) { |
| | | if (condition.getProjectIds().contains(project.getId())) { |
| | | condition.setProjectIds(Lists.newArrayList()); |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | condition.addProjectIds(project.getId()); |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // 이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다. |
| | | private void notFoundIssueList(Map<String, Object> resJsonData, Pageable pageable) { |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, Lists.newArrayList()); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | 0, 0)); |
| | | } |
| | | |
| | | // 사용자 정의 필드를 사용한 이슈를 찾는다. 만약 이슈가 없다면 여기서 이슈 조회가 끝난다. |
| | | private boolean searchUseCustomFields(IssueCondition condition, Set<String> issueIds, Map<String, Object> resJsonData, Pageable pageable) { |
| | | // 사용자 정의 필드 값이 검색 옵션으로 있었을 때 조회된 이슈가 없으면 조회를 더 이상 할 필요가 없다. |
| | | // 사용자 정의 필드를 사용한 이슈를 찾는다. |
| | | boolean customFieldSearch = this.issueCustomFieldValueService.find(condition, issueIds); |
| | | |
| | | // 사용자 정의 필드 값이 존재하여 검색을 했을 때 검색된 이슈가 없으면 여기서 종료한다. |
| | | if (customFieldSearch && issueIds.size() < 1) { |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, Lists.newArrayList()); |
| | | |
| | | if (pageable != null) { |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | 0, 0)); |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // 이슈 담당자 정보를 셋팅한다. |
| | | private void setIssueUserList(List<IssueVo> issueVos, IssueCondition issueCondition) { |
| | | if (issueVos.size() < 1) { |
| | | return; |
| | | } |
| | | |
| | | List<Map<String, Object>> issueUsers = this.issueMapper.findIssueUser(issueCondition); |
| | | Map<String, Object> issueConverterUsers = new HashMap<>(); |
| | | |
| | | // 이슈에 해당하는 이슈 담당자 정보 셋팅 |
| | | for (Map<String, Object> issueUser : issueUsers) { |
| | | String issueId = MapUtil.getString(issueUser, "issueId"); |
| | | |
| | | if (MapUtil.getObject(issueConverterUsers, issueId) != null) { |
| | | List<UserVo> users = (List) MapUtil.getObject(issueConverterUsers, issueId); |
| | | users.add(new UserVo(MapUtil.getLong(issueUser, "id"), MapUtil.getString(issueUser, "name"), CommonUtil.decryptAES128(MapUtil.getString(issueUser, "account")), MapUtil.getString(issueUser, "profile"))); |
| | | } else { |
| | | List<UserVo> users = Lists.newArrayList(new UserVo(MapUtil.getLong(issueUser, "id"), MapUtil.getString(issueUser, "name"), CommonUtil.decryptAES128(MapUtil.getString(issueUser, "account")), |
| | | MapUtil.getString(issueUser, "profile"))); |
| | | issueConverterUsers.put(issueId, users); |
| | | } |
| | | } |
| | | |
| | | // 이슈Vo에 담당자 정보를 셋팅 |
| | | for (IssueVo issueVo : issueVos) { |
| | | if (MapUtil.getObject(issueConverterUsers, String.valueOf(issueVo.getId())) != null) { |
| | | List<UserVo> userVos = (List) MapUtil.getObject(issueConverterUsers, String.valueOf(issueVo.getId())); |
| | | |
| | | issueVo.setUserVos(userVos); |
| | | } |
| | | |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | if (this.checkHasPermission(issueVo, issueVo.getUserVos())) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition) { |
| | | IssueVo issueVo = new IssueVo(); |
| | | |
| | | if (issueCondition.getId() != null) { |
| | | Issue issue = this.getIssue(issueCondition.getId()); |
| | | issueVo = ConvertUtil.copyProperties(issue, IssueVo.class); |
| | | |
| | | switch (issueCondition.getDeep()) { |
| | | case "01": // 프로젝트, 이슈 유형, 이슈 상태, 우선순위, 중요도, 담당자, 첨부파일, 사용자 정의 필드 정보를 셋팅한다. |
| | | issueVo.setProjectVo(ConvertUtil.copyProperties(issue.getProject(), ProjectVo.class)); |
| | | issueVo.setIssueTypeVo(ConvertUtil.copyProperties(issue.getIssueType(), IssueTypeVo.class)); |
| | | issueVo.setIssueStatusVo(ConvertUtil.copyProperties(issue.getIssueStatus(), IssueStatusVo.class)); |
| | | issueVo.setPriorityVo(ConvertUtil.copyProperties(issue.getPriority(), PriorityVo.class)); |
| | | issueVo.setSeverityVo(ConvertUtil.copyProperties(issue.getSeverity(), SeverityVo.class)); |
| | | |
| | | this.setRegister(issue, issueVo); // 등록자 정보 셋팅 |
| | | this.setIssueUser(issue, issueVo); // 담당자 정보 셋팅 |
| | | this.setAttachedFiles(issue, issueVo); // 첨부 파일 정보 셋팅 |
| | | this.setIssueCustomFields(issue, issueVo); // 사용자 정의 필드 값 정보 셋팅 |
| | | this.setRelationIssue(issue, issueVo); //연관 일감 셋팅 |
| | | break; |
| | | |
| | | case "02": // 프로젝트, 이슈 유형, 이슈 상태, 우선순위, 중요도, 담당자, 첨부파일, 사용자 정의 필드 정보, 댓글, 기록을 셋팅한다. |
| | | this.setIssueDetail(issueVo, issue); // 이슈 상세 정보를 셋팅한다. |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_DETAIL)); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVo); |
| | | } |
| | | |
| | | // 이슈 상세 정보를 셋팅한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void setIssueDetail(IssueVo issueVo, Issue issue) { |
| | | issueVo.setProjectVo(ConvertUtil.copyProperties(issue.getProject(), ProjectVo.class)); |
| | | issueVo.setIssueTypeVo(ConvertUtil.copyProperties(issue.getIssueType(), IssueTypeVo.class)); |
| | | IssueStatusVo issueStatusVo = ConvertUtil.copyProperties(issue.getIssueStatus(), IssueStatusVo.class, "issueStatusType"); |
| | | issueStatusVo.setIssueStatusType(issue.getIssueStatus().getIssueStatusType().toString()); |
| | | issueVo.setIssueStatusVo(issueStatusVo); |
| | | issueVo.setPriorityVo(ConvertUtil.copyProperties(issue.getPriority(), PriorityVo.class)); |
| | | issueVo.setSeverityVo(ConvertUtil.copyProperties(issue.getSeverity(), SeverityVo.class)); |
| | | this.setRegister(issue, issueVo); // 등록자 정보 셋팅 |
| | | this.setIssueUser(issue, issueVo); // 담당자 정보 셋팅 |
| | | this.setAttachedFiles(issue, issueVo); // 첨부 파일 정보 셋팅 |
| | | this.setIssueCustomFields(issue, issueVo); // 사용자 정의 필드 값 정보 셋팅 |
| | | this.setIssueComments(issue, issueVo); // 댓글 정보 셋팅 |
| | | this.setIssueHistory(issue, issueVo); // 이슈 기록 정보 셋팅 |
| | | this.setRelationIssue(issue, issueVo); //연관 일감 셋팅 |
| | | } |
| | | |
| | | // 등록자 정보 추가 |
| | | private void setRegister(List<IssueVo> issueVos) { |
| | | for (IssueVo issueVo : issueVos) { |
| | | // 사용자 패스워드를 삭제하고 사용자 계정을 복호화한다. |
| | | issueVo.setRegisterVo(this.userService.removeSensitiveUser(issueVo.getRegisterId())); |
| | | } |
| | | } |
| | | |
| | | // 이슈 등록자 정보를 셋팅한다. |
| | | private void setRegister(Issue issue, IssueVo issueVo) { |
| | | UserVo userVo = this.userService.removeSensitiveUser(issue.getRegisterId()); |
| | | issueVo.setRegisterVo(userVo); |
| | | |
| | | // 등록자는 항상 수정 가능. |
| | | if (userVo.getId().equals(this.webAppUtil.getLoginId())) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | | |
| | | // 연관 이슈 정보를 셋팅한다 |
| | | private void setRelationIssue(Issue issue, IssueVo issueVo) { |
| | | Set<IssueRelation> issueRelations = issue.getIssueRelations(); |
| | | if (issue != null && issueVo != null && issueRelations.size() > 0) { |
| | | for (IssueRelation issueRelation : issueRelations) { |
| | | IssueRelationVo issueRelationVo = ConvertUtil.copyProperties(issueRelation, IssueRelationVo.class); |
| | | |
| | | Issue relationIssue = issueRelation.getRelationIssue(); |
| | | |
| | | IssueVo relIssueVo = ConvertUtil.copyProperties(relationIssue, IssueVo.class); |
| | | Project project = this.projectService.getProject(relationIssue.getProject().getId()); |
| | | relIssueVo.setProjectId(project.getId()); |
| | | relIssueVo.setProjectKey(project.getProjectKey()); |
| | | relIssueVo.setIssueNumber(relationIssue.getIssueNumber()); |
| | | |
| | | issueRelationVo.setIssueRelation(relIssueVo); |
| | | issueRelationVo.setTitle(relationIssue.getTitle()); |
| | | issueVo.addIssueRelationVo(issueRelationVo); |
| | | } |
| | | } else { |
| | | issue.clearIssueRelations(); |
| | | } |
| | | } |
| | | |
| | | // 이슈 담당자 정보를 셋팅한다. |
| | | private void setIssueUser(Issue issue, IssueVo issueVo) { |
| | | List<UserVo> userVos = Lists.newArrayList(); |
| | | |
| | | for (IssueUser issueUser : issue.getIssueUsers()) { |
| | | UserVo userVo = ConvertUtil.copyProperties(issueUser.getUser(), UserVo.class, "password"); |
| | | userVo.setByName(userVo.getName() + "(" + CommonUtil.decryptAES128(userVo.getAccount()) + ")"); |
| | | userVo.setAccount(CommonUtil.decryptAES128(userVo.getAccount())); |
| | | userVos.add(userVo); |
| | | // 담당자가 있을 경우 담당자만 수정 가능. |
| | | if (userVo.getId().equals(this.webAppUtil.getLoginId())) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | | |
| | | // 스케쥴러에서 실행될 경우 오류 발생하므로 권한 체크하지 않는다. |
| | | if (this.webAppUtil.getLoginId() != null) { |
| | | // 업무 공간 관리자일 경우 수정 권한을 갖는다. |
| | | if (this.userWorkspaceService.checkWorkspaceManager()) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | |
| | | // 프로젝트 관리자일 경우 해당 프로젝트에 등록된 이슈는 수정 권한을 갖는다. |
| | | if (this.projectRoleUserService.checkProjectManager(issue.getProject())) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | | |
| | | // 담당자가 없으면 모든 사용자가 수정 가능. |
| | | if (issue.getIssueUsers().size() < 1) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | |
| | | issueVo.setUserVos(userVos); |
| | | } |
| | | |
| | | // 이슈 첨부파일 정보를 셋팅한다. |
| | | private void setAttachedFiles(Issue issue, IssueVo issueVo) { |
| | | List<AttachedFileVo> attachedFileVos = Lists.newArrayList(); |
| | | |
| | | for (AttachedFile attachedFile : issue.getAttachedFiles()) { |
| | | AttachedFileVo attachedFileVo = ConvertUtil.copyProperties(attachedFile, AttachedFileVo.class, "fileType"); |
| | | attachedFileVo.setFileType(attachedFile.getFileType().toString()); |
| | | attachedFileVos.add(attachedFileVo); |
| | | } |
| | | |
| | | issueVo.setAttachedFileVos(attachedFileVos); |
| | | } |
| | | |
| | | // 이슈(이슈 유형)에 연결된 사용자 정의 필드 정보를 셋팅한다. |
| | | private void setIssueCustomFields(Issue issue, IssueVo issueVo) { |
| | | |
| | | // 해당 프로젝트의 이슈 유형에 연결된 사용자 정의 필드 정보를 가져온다. |
| | | IssueTypeCustomFieldCondition issueTypeCustomFieldCondition = new IssueTypeCustomFieldCondition(); |
| | | issueTypeCustomFieldCondition.setProjectId(issue.getProject().getId()); |
| | | issueTypeCustomFieldCondition.setIssueTypeId(issue.getIssueType().getId()); |
| | | List<IssueTypeCustomFieldVo> issueTypeCustomFieldVos = this.issueTypeCustomFieldService.findIssueTypeCustomField(new HashMap<>(), issueTypeCustomFieldCondition); |
| | | issueVo.setIssueTypeCustomFieldVos(issueTypeCustomFieldVos); |
| | | |
| | | // 이슈에서 사용된 사용자 정의 필드 값을 가져온다. |
| | | List<IssueCustomFieldValueVo> issueCustomFieldValueVos = this.issueCustomFieldValueService.findByIssueId(issue.getId()); |
| | | issueVo.setIssueCustomFieldValueVos(issueCustomFieldValueVos); |
| | | } |
| | | |
| | | // 이슈에 등록된 댓글 정보를 셋팅한다. |
| | | private void setIssueComments(Issue issue, IssueVo issueVo) { |
| | | issueVo.setIssueCommentVos(this.issueCommentService.findIssueComment(issue.getId())); |
| | | } |
| | | |
| | | // 이슈 기록 정보를 셋팅한다. |
| | | private void setIssueHistory(Issue issue, IssueVo issueVo) { |
| | | issueVo.setIssueHistoryVos(this.issueHistoryService.findIssueHistory(issue.getId())); |
| | | } |
| | | |
| | | // 이슈를 수정한다. |
| | | @Override |
| | | @Transactional |
| | | public Issue modifyIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 이슈 수정 권한 체크 |
| | | this.verifyIssueModifyPermission(issueForm.getId()); |
| | | // 프로젝트 유효성 체크 |
| | | Project project = this.projectService.getProject(issueForm.getProjectId()); |
| | | // 이슈 상태 유효성 체크 |
| | | IssueStatus issueStatus = this.issueStatusService.getIssueStatus(issueForm.getIssueStatusId()); |
| | | // 이슈 유형 유효성 체크 |
| | | IssueType issueType = this.issueTypeService.getIssueType(issueForm.getIssueTypeId()); |
| | | // 우선순위 유효성 체크 |
| | | Priority priority = this.priorityService.getPriority(issueForm.getPriorityId()); |
| | | // 중요도 유효성 체크 |
| | | Severity severity = this.severityService.getSeverity(issueForm.getSeverityId()); |
| | | // 제목 유효성 체크 |
| | | this.verifyTitle(issueForm.getTitle()); |
| | | // 날짜 유효성 체크 |
| | | this.checkStartCompleteDate(issueForm.getStartDate(), issueForm.getCompleteDate()); |
| | | |
| | | // 담당자 유효성 체크 |
| | | this.verifyIssueAssignee(project, issueForm); |
| | | |
| | | Issue issue = this.getIssue(issueForm.getId()); |
| | | |
| | | // 변경 이력 정보 추출 |
| | | StringBuilder detectIssueChange = this.issueHistoryService.detectIssueChange(issue, issueForm, project, issueStatus, issueType, priority, severity, multipartFiles); |
| | | |
| | | // 프로젝트가 변경되면 이슈 넘버를 새로 따야 한다. |
| | | this.checkChangeProject(project, issue); |
| | | |
| | | // 이슈 유형이 변경되었는지 확인하고 변경되었다면 이슈 상태 속성이 '대기' 인 이슈 상태로 교체한다. |
| | | if (this.checkChangeIssueType(issueType, issueStatus, issue)) { |
| | | issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow()); |
| | | // 이슈 상태 변경 이력 남기기 - 이력을 남기기 위해 issueForm 에 issueStatus Id 값을 저장. |
| | | issueForm.setIssueStatusId(issueStatus.getId()); |
| | | this.issueHistoryService.detectIssueStatus(issue, issueForm, detectIssueChange, issueStatus); |
| | | } |
| | | |
| | | ConvertUtil.copyProperties(issueForm, issue, "id"); |
| | | issue.setProject(project); |
| | | issue.setIssueStatus(issueStatus); |
| | | issue.setIssueType(issueType); |
| | | issue.setPriority(priority); |
| | | issue.setSeverity(severity); |
| | | issue.setStartDate(issueForm.getStartDate()); |
| | | issue.setCompleteDate(issueForm.getCompleteDate()); |
| | | |
| | | this.issueRepository.saveAndFlush(issue); |
| | | // 담당자 지정 |
| | | this.issueUserService.modifyIssueUser(issue, project.getWorkspace(), issueForm.getUserIds()); |
| | | |
| | | // multipartFile 을 file Map List 객체로 변경한다. |
| | | List<Map<String, Object>> convertFileMaps = this.convertMultipartFileToFile(multipartFiles); |
| | | |
| | | // 첨부 파일 저장 - 비동기로 작동 |
| | | this.attachedFileService.addAttachedFile(convertFileMaps, issue, this.webAppUtil.getLoginUser().getAccount()); |
| | | // 삭제된 첨부파일 처리 |
| | | this.attachedFileService.removeAttachedFiles(issueForm.getRemoveFiles()); |
| | | // 텍스트 에디터에 첨부한 파일을 이슈와 연결 |
| | | this.checkNotHaveIssueIdAttachedFile(issue, issueForm); |
| | | // 사용자 정의 필드 저장 |
| | | this.issueCustomFieldValueService.modifyIssueCustomFieldValue(issue, issueForm.getIssueCustomFields()); |
| | | // 이슈 이력 등록 |
| | | if (!StringUtils.isEmpty(detectIssueChange.toString())) { |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.MODIFY, detectIssueChange.toString()); |
| | | } |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_MODIFY)); |
| | | |
| | | return issue; |
| | | } |
| | | |
| | | // multipartFile 을 file Map 객체로 변경한다. |
| | | private List<Map<String, Object>> convertMultipartFileToFile(List<MultipartFile> multipartFiles) { |
| | | List<Map<String, Object>> convertFileMaps = Lists.newArrayList(); |
| | | |
| | | for (MultipartFile multipartFile : multipartFiles) { |
| | | try { |
| | | Map<String, Object> fileMap = CommonUtil.makeFileMap(multipartFile); |
| | | convertFileMaps.add(fileMap); |
| | | } catch (Exception e) { |
| | | log.debug("multipartFile -> file 변환 오류" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | return convertFileMaps; |
| | | } |
| | | |
| | | // 프로젝트가 변경되었는지 확인한다. |
| | | private void checkChangeProject(Project newProject, Issue issue) { |
| | | if (!issue.getProject().getId().equals(newProject.getId())) { |
| | | // 각 프로젝트의 고유 이슈 번호 생성 |
| | | issue.setIssueNumber(this.issueNumberGeneratorService.generateIssueNumber(newProject)); |
| | | } |
| | | } |
| | | |
| | | // 이슈 유형이 변경되었는지 확인하고 변경되었으면 이슈 상태를 대기 속성인 이슈 상태로 셋팅한다. |
| | | private Boolean checkChangeIssueType(IssueType newIssueType, IssueStatus issueStatus, Issue issue) { |
| | | if (!issue.getIssueType().getId().equals(newIssueType.getId())) { |
| | | // 이슈 상태를 선택하지 않았을 때 |
| | | if (issueStatus == null) { |
| | | return true; |
| | | } |
| | | |
| | | // 이슈 상태의 속성이 '대기' 가 아닌 경우 |
| | | if (!issueStatus.getIssueStatusType().equals(IssueStatusType.READY)) { |
| | | return true; |
| | | } else { |
| | | // 변경하는 이슈 유형의 워크플로우에 존재하는 상태 속성 '대기'와 동일한 상태인지 확인 |
| | | IssueStatus newReadyIssueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(newIssueType.getWorkflow()); |
| | | |
| | | if (!newReadyIssueStatus.getId().equals(issueStatus.getId())) { |
| | | return true; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | // 이슈 담당자로 지정될 사용자가 해당 프로젝트에 참여 하고 있는 사용자 인지 확인 |
| | | private void verifyIssueAssignee(Project project, IssueForm issueForm) { |
| | | if (issueForm.getUserIds().size() > 0) { |
| | | List<Long> trustUserIds = Lists.newArrayList(); // 참여 확인된 사용자 |
| | | |
| | | for (Long userId : issueForm.getUserIds()) { |
| | | boolean includeProject = false; |
| | | |
| | | for (ProjectRole projectRole : project.getProjectRoles()) { |
| | | ProjectRoleUser projectRoleUser = this.projectRoleUserService.findByProjectRoleIdAndUserId(projectRole.getId(), userId); |
| | | |
| | | if (projectRoleUser != null) { |
| | | includeProject = true; |
| | | trustUserIds.add(userId); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 데이터 보정 작업 - 프로젝트에서 제외된 사용자는 담당자에서 제외 될 수 있도록 처리 |
| | | /*if (!includeProject) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_INCLUDE_USER)); |
| | | }*/ |
| | | } |
| | | // 참여 확인된 사용자로 담당자 변경 |
| | | issueForm.setUserIds(trustUserIds); |
| | | } |
| | | } |
| | | |
| | | // 이슈 수정 권한 체크 |
| | | private void verifyIssueModifyPermission(Long issueId) { |
| | | Issue issue = this.getIssue(issueId); |
| | | |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | if (!this.checkHasPermission(ConvertUtil.copyProperties(issue, IssueVo.class), this.getIssueUserVos(issue))) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_MODIFY_PERMISSION)); |
| | | } |
| | | } |
| | | |
| | | // 이슈에서 담당자 정보를 추출한다. |
| | | private List<UserVo> getIssueUserVos(Issue issue) { |
| | | List<UserVo> userVos = Lists.newArrayList(); |
| | | |
| | | for (IssueUser issueUser : issue.getIssueUsers()) { |
| | | UserVo userVo = ConvertUtil.copyProperties(issueUser.getUser(), UserVo.class, "password"); |
| | | userVos.add(userVo); |
| | | } |
| | | |
| | | return userVos; |
| | | } |
| | | |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | private boolean checkHasPermission(IssueVo issueVo, List<UserVo> issueUserVos) { |
| | | boolean hasPermission = false; |
| | | |
| | | // 업무 공간 관리자일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.WORKSPACE_MANAGER, issueVo, null); |
| | | // 프로젝트 관리자일 경우 해당 프로젝트에 등록된 이슈는 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.PROJECT_MANAGER, issueVo, null); |
| | | // 이슈 등록자일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.REGISTER, issueVo, null); |
| | | // 이슈 담당자일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ASSIGNEE, issueVo, issueUserVos); |
| | | // 담당자가 없으면 모든 사용자가 수정 권한을 갖는다. |
| | | |
| | | return hasPermission; |
| | | } |
| | | |
| | | // 이슈 수정 권한을 확인한다. |
| | | private boolean checkIssueModifyPermission(Boolean hasPermission, String checkType, IssueVo issueVo, List<UserVo> issueUserVos) { |
| | | if (!hasPermission) { |
| | | switch (checkType) { |
| | | case Issue.WORKSPACE_MANAGER: // 업무 공간 관리자 |
| | | // 업무 공간 관리자일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.userWorkspaceService.checkWorkspaceManager(); |
| | | break; |
| | | |
| | | case Issue.PROJECT_MANAGER: // 프로젝트 관리자 |
| | | Issue issue = this.getIssue(issueVo.getId()); |
| | | // 프로젝트 관리자일 경우 해당 프로젝트에 등록된 이슈는 수정 권한을 갖는다. |
| | | hasPermission = this.projectRoleUserService.checkProjectManager(issue.getProject()); |
| | | break; |
| | | |
| | | case Issue.REGISTER: // 이슈 등록자 |
| | | hasPermission = issueVo.getRegisterId().equals(this.webAppUtil.getLoginId()); |
| | | break; |
| | | |
| | | case Issue.ASSIGNEE: |
| | | // 담당자가 없으면 모든 사용자가 수정 권한을 갖는다. |
| | | if (issueUserVos.size() < 1) { |
| | | hasPermission = true; |
| | | break; |
| | | } |
| | | |
| | | // 이슈 담당자 여부 확인 |
| | | for (UserVo issueUserVo : issueUserVos) { |
| | | if (issueUserVo.getId().equals(this.webAppUtil.getLoginId())) { |
| | | hasPermission = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return hasPermission; |
| | | } |
| | | |
| | | // 이슈 상태 변경 |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueStatus(IssueForm issueForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 변경 이력 정보 추출 |
| | | StringBuilder detectIssueChange = new StringBuilder(); |
| | | // 이슈 수정 권한 체크 |
| | | this.verifyIssueModifyPermission(issueForm.getId()); |
| | | Issue issue = this.getIssue(issueForm.getId()); |
| | | |
| | | IssueStatus issueStatus = this.issueStatusService.getIssueStatus(issueForm.getIssueStatusId()); |
| | | // 이슈 상태를 변경할 때 선택한 이슈 상태로 변경할 수 있는지 확인한다. |
| | | this.issueStatusService.checkNextIssueStatus(issue, issueStatus); |
| | | // 변경 이력 정보 추출 |
| | | this.issueHistoryService.detectIssueStatus(issue, issueForm, detectIssueChange, issueStatus); |
| | | |
| | | issue.setIssueStatus(issueStatus); |
| | | this.issueRepository.saveAndFlush(issue); |
| | | |
| | | // 코멘트 등록 |
| | | if (!StringUtils.isEmpty(issueForm.getComment())) { |
| | | IssueCommentForm issueCommentForm = new IssueCommentForm(); |
| | | issueCommentForm.setIssueId(issue.getId()); |
| | | issueCommentForm.setDescription(issueForm.getComment()); |
| | | this.issueCommentService.addIssueComment(issueCommentForm); |
| | | } |
| | | |
| | | // 이슈 이력 등록 |
| | | if (!StringUtils.isEmpty(detectIssueChange.toString())) { |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | stringBuilder.append("<ul class=\"activity-list\">"); |
| | | stringBuilder.append(detectIssueChange.toString()); |
| | | stringBuilder.append("</ul>"); |
| | | |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.MODIFY, stringBuilder.toString()); |
| | | } |
| | | |
| | | // 이슈 버전 생성 |
| | | this.issueVersionService.addIssueVersion(issue); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_STATUS_CHANGE)); |
| | | } |
| | | |
| | | // 이슈 담당자 변경 |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueUser(IssueForm issueForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 변경 이력 정보 추출 |
| | | StringBuilder detectIssueChange = new StringBuilder(); |
| | | // 이슈 수정 권한 체크 |
| | | this.verifyIssueModifyPermission(issueForm.getId()); |
| | | Issue issue = this.getIssue(issueForm.getId()); |
| | | issue.setProject(this.projectService.getProject(issueForm.getProjectId())); |
| | | |
| | | // 변경 이력 정보 추출 |
| | | this.issueHistoryService.detectIssueManager(issue, issueForm, detectIssueChange); |
| | | |
| | | this.issueUserService.modifyIssueUser(issue, issue.getProject().getWorkspace(), issueForm.getUserIds()); |
| | | this.issueRepository.saveAndFlush(issue); |
| | | |
| | | // 이슈 이력 등록 |
| | | if (!StringUtils.isEmpty(detectIssueChange.toString())) { |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | stringBuilder.append("<ul class=\"activity-list\">"); |
| | | stringBuilder.append(detectIssueChange.toString()); |
| | | stringBuilder.append("</ul>"); |
| | | |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.MODIFY, stringBuilder.toString()); |
| | | } |
| | | |
| | | // 이슈 버전 생성 |
| | | this.issueVersionService.addIssueVersion(issue); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_USER_CHANGE)); |
| | | } |
| | | |
| | | // 이슈를 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssues(IssueForm issueForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | if (issueForm.getRemoveIds().size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_REMOVE_NOT_SELECT)); |
| | | } |
| | | |
| | | List<Issue> removeIssues = Lists.newArrayList(); |
| | | |
| | | for (Long issueId : issueForm.getRemoveIds()) { |
| | | Issue issue = this.issueRemoves(issueId); |
| | | removeIssues.add(issue); |
| | | } |
| | | |
| | | if (removeIssues.size() > 0) { |
| | | //this.issueRepository.deleteAll(removeIssues); |
| | | } |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_REMOVE)); |
| | | } |
| | | |
| | | private Issue issueRemoves(Long issueId) { |
| | | Issue issue = this.getIssue(issueId); |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | this.verifyIssueModifyPermission(issueId); |
| | | |
| | | // 이슈 첨부 파일을 삭제한다. |
| | | if (issue.getAttachedFiles().size() > 0) { |
| | | List<Long> attachedFileIds = Lists.newArrayList(); |
| | | |
| | | for (AttachedFile attachedFile : issue.getAttachedFiles()) { |
| | | attachedFileIds.add(attachedFile.getId()); |
| | | } |
| | | // 첨부파일 삭제 |
| | | this.attachedFileService.removeAttachedFiles(attachedFileIds); |
| | | } |
| | | |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | this.reservationIssueEmail(issue.getId(), EmailType.ISSUE_REMOVE); |
| | | // 이슈 삭제 |
| | | this.issueRepository.delete(issue); |
| | | |
| | | return issue; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Issue getIssue(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_EXIST)); |
| | | } |
| | | |
| | | Issue issue = this.findOne(id); |
| | | |
| | | if (issue == null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_EXIST)); |
| | | } |
| | | |
| | | return issue; |
| | | } |
| | | |
| | | // 이슈 유형을 사용하는 이슈 갯수를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public long countByIssueTypeId(Long issueTypeId) { |
| | | return this.issueMapper.countByIssueTypeId(issueTypeId); |
| | | } |
| | | |
| | | // 이슈 상태를 사용하는 이슈 갯수를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public long countByIssueStatus(Long issueStatusId) { |
| | | return this.issueMapper.countByIssueStatusId(issueStatusId); |
| | | } |
| | | |
| | | // 이슈 유형에서 워크플로우가 변경되었을 때 해당 워크플로우에 현재 이슈 상태가 존재하지 않으면 대기(생성) 로 변경한다. |
| | | @Override |
| | | @Transactional |
| | | public void changeWorkflows(Workflow workflow, IssueType issueType) { |
| | | List<Map<String, Object>> issueMaps = this.issueMapper.findByIssueTypeId(issueType.getId()); |
| | | List<IssueStatusVo> issueStatusVos = this.issueStatusService.findByWorkflowId(workflow.getId()); |
| | | IssueStatus readyIssueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(workflow); |
| | | List<Issue> updateIssues = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> issueMap : issueMaps) { |
| | | boolean exist = false; |
| | | |
| | | for (IssueStatusVo issueStatusVo : issueStatusVos) { |
| | | Long issueStatusId = MapUtil.getLong(issueMap, "issueStatusId"); |
| | | if (issueStatusId == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | |
| | | if (issueStatusId.equals(issueStatusVo.getId())) { |
| | | exist = true; |
| | | break; |
| | | } |
| | | } |
| | | // 존재하지 않는 대상은 |
| | | if (!exist) { |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | String issueStatusName = MapUtil.getString(issueMap, "issueStatusName"); |
| | | if (issueStatusName == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | |
| | | Issue issue = this.getIssue(MapUtil.getLong(issueMap, "issueId")); |
| | | |
| | | // 워크플로우에서 이슈 상태가 삭제되어 상태가 변경된 정보를 기록한다. |
| | | this.issueHistoryService.recordRemoveWorkflowToIssueStatus(issueStatusName, readyIssueStatus.getName(), stringBuilder); |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.MODIFY, stringBuilder.toString()); |
| | | |
| | | issue.setIssueStatus(readyIssueStatus); |
| | | updateIssues.add(issue); |
| | | } |
| | | } |
| | | |
| | | if (updateIssues.size() > 0) { |
| | | this.issueRepository.saveAll(updateIssues); |
| | | |
| | | for (Issue issue : updateIssues) { |
| | | // 이슈 버전 생성 |
| | | this.issueVersionService.addIssueVersion(issue); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈 목록을 엑셀로 다운로드 한다. |
| | | @Override |
| | | @Transactional |
| | | public ModelAndView downloadExcel(HttpServletRequest request, Model model) { |
| | | |
| | | // 사용 공간에서 로그인한 사용자가 비활성인지 확인하고 비활성일 경우 엑셀 다운로드를 금지한다. |
| | | ModelAndView modelAndView = this.workspaceService.checkUseExcelDownload(model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | Map<String, Object> conditions = new HashMap<>(); |
| | | // 엑셀 다운로드에 필요한 검색 조건 정보를 추출하고 검색 조건 추출에 오류가 발생하면 경고를 표시해준다. |
| | | modelAndView = this.excelConditionCheck.checkCondition(conditions, request, model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | IssueCondition issueCondition = IssueCondition.make(conditions); |
| | | // 검색 조건을 만든다 |
| | | this.makeIssueSearchCondition(issueCondition, Lists.newArrayList("01", "02", "03"), null); |
| | | |
| | | Set<String> issueIds = new HashSet<>(); // 사용자 정의 필드 검색시 나오는 이슈 아이디 저장 컬렉션 |
| | | Map<String, Object> resJsonData = new HashMap<>(); |
| | | |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.setFileName(this.messageAccessor.message("common.issueList")); // 이슈 목록 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("issueStatusName", this.messageAccessor.message("common.status"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 상태 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("issueKey", this.messageAccessor.message("common.issueKey"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 이슈 번호 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("title", this.messageAccessor.message("common.issueTitle"), 40, ExportExcelAttrVo.ALIGN_LEFT)); // 이슈 제목 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("description", this.messageAccessor.message("common.content"), 60, ExportExcelAttrVo.ALIGN_LEFT)); // 내용 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("issueTypeName", this.messageAccessor.message("common.issueType"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 이슈 타입 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("assignees", this.messageAccessor.message("common.assignee"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 담당자 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("priorityName", this.messageAccessor.message("common.priority"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 우선순위 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("severityName", this.messageAccessor.message("common.importance"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 중요도 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("register", this.messageAccessor.message("common.register"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 등록자 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("period", this.messageAccessor.message("common.period"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 기간 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("modifyDate", this.messageAccessor.message("common.modifyDate"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 최종 변경일 |
| | | |
| | | |
| | | // 사용자 정의 필드를 사용한 이슈를 찾는다. 만약 이슈가 없다면 여기서 이슈 조회가 끝난다. |
| | | if (!this.searchUseCustomFields(issueCondition, issueIds, resJsonData, null)) { |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | List<IssueVo> issueVos = Lists.newArrayList(); // 이슈 목록 데이터 저장 컬렉션 |
| | | // 사용자 정의 필드로 검색한 이슈 아이디 값 |
| | | List<String> issueKeys = Lists.newArrayList(issueIds); |
| | | issueCondition.setIssueIds(issueKeys); |
| | | |
| | | List<Map<String, Object>> results = this.issueMapper.find(issueCondition); |
| | | // 엑셀 다운로드를 진행할 때 전체 사용자 정의 필드를 표시한다. |
| | | this.makeIssueExcelDownloadCustomFields(excelInfo); |
| | | |
| | | // 이슈 아이디 초기화 |
| | | issueCondition.setIssueIds(Lists.newArrayList()); |
| | | |
| | | // Map 에 있는 데이터를 IssueVo 데이터로 변환한다. |
| | | this.setMapToIssueVo(results, issueVos, issueCondition); |
| | | |
| | | // IssueVos 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | List<Map<String, String>> convertExcelViewToIssueMaps = this.convertExcelViewToIssueVos(issueVos); |
| | | |
| | | if (results.size() > EXCEL_DOWNLOAD_MAX_ROWS) { |
| | | // 엑셀 1만건 초과 알림 |
| | | this.simpMessagingTemplate.convertAndSendToUser(this.webAppUtil.getLoginUser().getAccount(), "/notification/system-alert", this.messageAccessor.getMessage(MsgConstants.EXCEL_DOWNLOAD_MAX_ROWS_OVER)); |
| | | |
| | | // 1만 건만 출력해준다. |
| | | excelInfo.setDatas(convertExcelViewToIssueMaps.subList(0, EXCEL_DOWNLOAD_MAX_ROWS)); |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | // 엑셀에 넣을 데이터 - IssueVos 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | excelInfo.setDatas(convertExcelViewToIssueMaps); |
| | | |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | // 엑셀 다운로드를 진행할 때 전체 사용자 정의 필드를 표시한다. |
| | | private void makeIssueExcelDownloadCustomFields(ExportExcelVo excelInfo) { |
| | | List<CustomField> customFields = this.customFieldService.findByWorkspaceId(); |
| | | |
| | | for (CustomField customField : customFields) { |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("customField_" + customField.getId(), customField.getName(), 10, ExportExcelAttrVo.ALIGN_CENTER)); |
| | | } |
| | | } |
| | | |
| | | // 사용자 정의 필드 정보 추가 |
| | | private void setIssueCustomFieldValue(List<IssueVo> issueVos, IssueCondition issueCondition) { |
| | | // 이슈에서 저장한 사용자 정의 필드 값을 조회한다. |
| | | List<Map<String, Object>> issueCustomFieldValues = this.issueCustomFieldValueService.findInIssueIds(issueCondition); |
| | | |
| | | for (IssueVo issueVo : issueVos) { |
| | | for (Map<String, Object> issueCustomFieldValue : issueCustomFieldValues) { |
| | | if (issueVo.getId().equals(MapUtil.getLong(issueCustomFieldValue, "issueId"))) { |
| | | IssueCustomFieldValueVo issueCustomFieldValueVo = new IssueCustomFieldValueVo(); |
| | | issueCustomFieldValueVo.setUseValue(MapUtil.getString(issueCustomFieldValue, "useValue")); |
| | | |
| | | CustomFieldVo customFieldVo = new CustomFieldVo(); |
| | | customFieldVo.setId(MapUtil.getLong(issueCustomFieldValue, "customFieldId")); |
| | | issueCustomFieldValueVo.setCustomFieldVo(customFieldVo); |
| | | issueVo.addIssueCustomFieldValueVo(issueCustomFieldValueVo); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 연관일감 정보 추가 |
| | | private void setRelationIssue(IssueVo issueVo, Long issueId) { |
| | | List<IssueVo> relationIssues = this.issueRelationService.findRelationIssue(issueId); |
| | | issueVo.setIssueRelationIssueVos(relationIssues); |
| | | } |
| | | |
| | | // IssueVos 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | private List<Map<String, String>> convertExcelViewToIssueVos(List<IssueVo> issueVos) { |
| | | List<Map<String, String>> results = Lists.newArrayList(); |
| | | |
| | | for (IssueVo issueVo : issueVos) { |
| | | try { |
| | | Map<String, String> result = new HashMap<>(); |
| | | result.put("issueStatusName", issueVo.getIssueStatusName()); |
| | | result.put("issueKey", issueVo.getProjectKey() + "-" + issueVo.getIssueNumber()); |
| | | result.put("title", issueVo.getTitle()); |
| | | |
| | | String description = ""; |
| | | |
| | | if (issueVo.getDescription() != null) { |
| | | description = Jsoup.parse(issueVo.getDescription()).text(); // HTML 태그 제거 |
| | | description = description.replaceAll("\\<.*?>", ""); // 공백 제거 |
| | | } |
| | | |
| | | result.put("description", description); |
| | | result.put("issueTypeName", issueVo.getIssueTypeName()); |
| | | result.put("assignees", CommonUtil.convertUserVosToString(issueVo.getUserVos())); |
| | | result.put("priorityName", issueVo.getPriorityName()); |
| | | result.put("severityName", issueVo.getSeverityName()); |
| | | |
| | | UserVo register = this.userService.removeSensitiveUser(issueVo.getRegisterId()); |
| | | // 등록자 |
| | | result.put("register", register.getByName()); |
| | | // 최종 변경일 |
| | | result.put("modifyDate", issueVo.getModifyDate()); |
| | | |
| | | if (StringUtils.isEmpty(issueVo.getStartDate())) { |
| | | result.put("period", ""); |
| | | } else { |
| | | result.put("period", issueVo.getStartDate() + " ~ " + issueVo.getCompleteDate()); |
| | | } |
| | | |
| | | for (IssueCustomFieldValueVo issueCustomFieldValueVo : issueVo.getIssueCustomFieldValueVos()) { |
| | | // 사용자 정의 필드 값 저장이 아직 안되어 있는 경우 |
| | | if (result.get("customField_" + issueCustomFieldValueVo.getCustomFieldVo().getId()) == null) { |
| | | result.put("customField_" + issueCustomFieldValueVo.getCustomFieldVo().getId().toString(), issueCustomFieldValueVo.getUseValue()); |
| | | } else { |
| | | // 이미 저장되어 있으면 다중 선택 사용자 정의 필드 값이다. |
| | | String useValue = result.get("customField_" + issueCustomFieldValueVo.getCustomFieldVo().getId()); |
| | | result.put("customField_" + issueCustomFieldValueVo.getCustomFieldVo().getId().toString(), useValue + ", " + issueCustomFieldValueVo.getUseValue()); |
| | | } |
| | | } |
| | | |
| | | results.add(result); |
| | | } catch (Exception e) { |
| | | log.error("엑셀 다운로드 오류 발생"); |
| | | } |
| | | } |
| | | |
| | | return results; |
| | | } |
| | | |
| | | // 이슈 다중 상태 변경 |
| | | @Override |
| | | @Transactional |
| | | public void modifyMultiIssueStatus(IssueForm issueForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | for (Long issueId : issueForm.getIds()) { |
| | | issueForm.setId(issueId); |
| | | // 이슈 상태 변경 |
| | | this.modifyIssueStatus(issueForm); |
| | | } |
| | | } |
| | | |
| | | // 이슈 Import 용 엑셀 템플릿 다운로드 |
| | | @Override |
| | | @Transactional |
| | | public ModelAndView downloadExcelTemplate(HttpServletRequest request, Model model) { |
| | | Map<String, Object> conditions; |
| | | |
| | | try { |
| | | // 엑셀 다운로드에 필요한 검색 조건 정보를 추출한다. |
| | | conditions = CommonUtil.getSearchConditions(request); |
| | | } catch (IOException e) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EXCEL_CONDITIONS_NOT_EXIST)); |
| | | } |
| | | |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.setHideCount(true); |
| | | excelInfo.setFileName(this.messageAccessor.message("common.registerExcelIssue")); // 엑셀로 이슈 등록하기 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.title"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 제목 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.content"), 40, ExportExcelAttrVo.ALIGN_CENTER)); // 내용 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.projectKey"), 10, ExportExcelAttrVo.ALIGN_LEFT)); // 프로젝트 키 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.issueType"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 이슈 타입 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.priority"), 5, ExportExcelAttrVo.ALIGN_CENTER)); // 우선순위 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.importance"), 5, ExportExcelAttrVo.ALIGN_CENTER)); // 중요도 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.assignee"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 담당자 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.startDate"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 시작일 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.endDate"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 종료일 |
| | | // 프로젝트에 연결된 사용자 정의 필드 정보를 추출하여 엑셀 download 템플릿을 만든다. |
| | | this.makeIssueExcelTemplateCustomFields(excelInfo, conditions); |
| | | // 엑셀에 넣을 데이터 - IssueVos 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | excelInfo.setDatas(Lists.newArrayList(new IssueVo())); |
| | | |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | // 프로젝트에 연결된 사용자 정의 필드 정보를 추출하여 엑셀 download 템플릿을 만든다. |
| | | private void makeIssueExcelTemplateCustomFields(ExportExcelVo excelInfo, Map<String, Object> conditions) { |
| | | List<IssueTypeCustomField> issueTypeCustomFields = this.issueTypeCustomFieldService.findByProjectIdAndIssueTypeId(MapUtil.getLong(conditions, "projectId"), MapUtil.getLong(conditions, "issueTypeId")); |
| | | |
| | | for (IssueTypeCustomField issueTypeCustomField : issueTypeCustomFields) { |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("id", issueTypeCustomField.getCustomField().getName(), 10, ExportExcelAttrVo.ALIGN_CENTER)); |
| | | } |
| | | } |
| | | |
| | | // 엑셀 import 로 이슈를 등록한다. |
| | | @Override |
| | | @Transactional |
| | | public void importExcel(MultipartFile multipartFile) throws Exception { |
| | | /*StopWatch serviceStart = new StopWatch(); |
| | | serviceStart.start();*/ |
| | | |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | if (multipartFile != null) { |
| | | // 업로드 파일 확장자 체크 |
| | | this.verifyMultipartFileExtension(multipartFile); |
| | | |
| | | Map<String, Project> projectMaps = new HashMap<>(); // 프로젝트 모음 |
| | | Map<String, IssueType> issueTypeMaps = new HashMap<>(); // 이슈 타입 모음 |
| | | Map<String, Priority> priorityMaps = new HashMap<>(); // 우선 순위 모음 |
| | | Map<String, Severity> severityMaps = new HashMap<>(); // 중요도 모음 |
| | | Map<String, Object> userMaps = new HashMap<>(); // 사용자 모음 |
| | | Map<String, CustomField> customFieldMaps = new HashMap<>(); |
| | | Map<String, IssueStatus> issueStatusReadyMaps = new HashMap<>(); // 상태 속성 '대기'인 이슈 상태 |
| | | Map<Long, Long> issueNumberMaps = new HashMap<>(); // 이슈 번호 모음 |
| | | Map<String, Long> issueTypeCustomFieldMaps = new HashMap<>(); // 이슈 타입 + 사용자 정의 필드 연결 정보 |
| | | Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); // 이슈를 넣으려는 업무 공간 |
| | | // 이슈의 주요 속성을 map 에 저장하여 엑셀 import 에서 지정한 대상(이슈 속성)을 빠르게 찾을 수 있게 한다. |
| | | this.IssueAttributeMapToList(projectMaps, issueTypeMaps, priorityMaps, severityMaps, userMaps, customFieldMaps, issueNumberMaps, issueTypeCustomFieldMaps, issueStatusReadyMaps); |
| | | // 0.237 - 0.230 |
| | | |
| | | List<IssueForm> issueForms = Lists.newArrayList(); |
| | | List<String> headers = Lists.newArrayList(); |
| | | |
| | | Workbook workbook; |
| | | |
| | | workbook = WorkbookFactory.create(multipartFile.getInputStream()); |
| | | Sheet sheet = workbook.getSheetAt(0); |
| | | int lastRowNum = sheet.getLastRowNum() + 1; |
| | | |
| | | // 2건 - 제목, 헤더 - 성능을 위해 최대 1만건으로 제한 |
| | | if (lastRowNum > (EXCEL_IMPORT_MAX_ROWS + 2)) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_MAX_ROWS_OVER)); |
| | | } |
| | | |
| | | for (int rowIndex = 0; rowIndex < lastRowNum; rowIndex++) { |
| | | // 0번은 헤더는 무시한다. |
| | | Row row = sheet.getRow(rowIndex); |
| | | // 헤더 정보를 추출한다 - 사용자 정의 필드 정보를 가져오기 위해 |
| | | if (rowIndex == 1) { |
| | | for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) { |
| | | Cell cell = row.getCell(cellIndex); |
| | | |
| | | if (cell == null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EXCEL_EMPTY_CELL)); |
| | | } |
| | | |
| | | // 엑셀 import 데이터에서 cell 값을 문자열로 변환한다. |
| | | String cellValue = CommonUtil.convertExcelStringToCell(cell); |
| | | |
| | | if (StringUtils.isEmpty(cellValue)) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EXCEL_HEADER_EMPTY_CELL)); |
| | | } |
| | | |
| | | headers.add(cellValue); |
| | | } |
| | | } |
| | | |
| | | // 1번 헤더부터 데이터 영역 |
| | | if (rowIndex > 1) { |
| | | // 이슈로 등록하기 위해 IssueForm 에 데이터를 셋팅한다. |
| | | issueForms.add(this.setIssueFormToExcelField(row, (rowIndex + 1), issueStatusReadyMaps, projectMaps, issueTypeMaps, priorityMaps, severityMaps, userMaps, customFieldMaps, issueNumberMaps, headers)); |
| | | } |
| | | } |
| | | |
| | | if (issueForms.size() < 1) { |
| | | return; |
| | | } |
| | | // 1.176 |
| | | |
| | | |
| | | // 이슈 등록 |
| | | this.issueMapper.insertBatch(issueForms); |
| | | // 0.416 - 0.439 |
| | | |
| | | // 1.373 ~ 1.394 |
| | | |
| | | // TODO - 이슈 이력 벌크 등록을 할 경우 프로필 이력 조회에서 부하가 심해서 넣을지 고민해야함. |
| | | // this.bulkInsertIssueHistory(issueForms); |
| | | |
| | | // 이슈 담당자 벌크 등록 |
| | | this.bulkInsertIssueAssignee(issueForms, workspace); |
| | | // 0.361 - 0.705 |
| | | |
| | | // 1.816 |
| | | /*StopWatch serviceStart = new StopWatch(); |
| | | serviceStart.start();*/ |
| | | // 이슈 사용자 정의 값 필드 벌크 등록 |
| | | this.bulkInsertIssueCustomFieldValue(issueForms, issueTypeCustomFieldMaps); |
| | | // 3.628 - 3.445 |
| | | |
| | | /*serviceStart.stop(); |
| | | log.debug("2차 저장 시간 : " + serviceStart.getTime());*/ |
| | | |
| | | // 이슈 리스크 벌크 등록 |
| | | this.bulkInsertIssueRisk(issueForms, workspace); |
| | | |
| | | // reverse index 업데이트 |
| | | this.issueMapper.updateBatch(issueForms); |
| | | // 증가된 이슈 번호를 업데이트 한다. |
| | | this.issueNumberGeneratorService.updateIssueNumber(issueNumberMaps); |
| | | } |
| | | } |
| | | |
| | | // 업로드 파일 확장자 체크 |
| | | private void verifyMultipartFileExtension(MultipartFile multipartFile) { |
| | | multipartFile.getOriginalFilename(); |
| | | |
| | | int pos = multipartFile.getOriginalFilename().lastIndexOf("."); |
| | | String ext = multipartFile.getOriginalFilename().substring(pos + 1); |
| | | |
| | | if (!ext.equals("xlsx")) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EXCEL_NOT_EXTENSION)); |
| | | } |
| | | } |
| | | |
| | | // 이슈 이력 벌크 등록 |
| | | private void bulkInsertIssueHistory(List<IssueForm> issueForms) { |
| | | List<Map<String, Object>> issueHistoryMaps = Lists.newArrayList(); |
| | | |
| | | for (IssueForm issueForm : issueForms) { |
| | | Map<String, Object> issueHistoryMap = new HashMap<>(); |
| | | issueHistoryMap.put("issueId", issueForm.getId()); |
| | | issueHistoryMap.put("projectId", issueForm.getProjectId()); |
| | | issueHistoryMap.put("registerId", this.webAppUtil.getLoginId()); |
| | | issueHistoryMap.put("issueHistoryType", IssueHistoryType.ADD.toString()); |
| | | |
| | | StringBuilder description = new StringBuilder(); |
| | | // 이력 테스트 추출 |
| | | this.issueHistoryService.makeDescription(description, IssueHistoryType.ADD, null); |
| | | issueHistoryMap.put("description", description.toString()); |
| | | |
| | | issueHistoryMaps.add(issueHistoryMap); |
| | | } |
| | | |
| | | // 이슈 이력 벌크 등록 |
| | | this.issueMapper.insertHistoryBatch(issueHistoryMaps); |
| | | } |
| | | |
| | | // 이슈 담당자 벌크 등록 |
| | | private void bulkInsertIssueAssignee(List<IssueForm> issueForms, Workspace workspace) { |
| | | List<Map<String, Long>> issueAssigneeMaps = Lists.newArrayList(); |
| | | |
| | | for (IssueForm issueForm : issueForms) { |
| | | for (Long userId : issueForm.getUserIds()) { |
| | | Map<String, Long> issueAssigneeMap = new HashMap<>(); |
| | | issueAssigneeMap.put("issueId", issueForm.getId()); |
| | | issueAssigneeMap.put("userId", userId); |
| | | issueAssigneeMap.put("workspaceId", workspace.getId()); |
| | | issueAssigneeMap.put("registerId", this.webAppUtil.getLoginId()); |
| | | issueAssigneeMaps.add(issueAssigneeMap); |
| | | } |
| | | } |
| | | |
| | | if (issueAssigneeMaps.size() > 0) { |
| | | // 이슈 담당자 벌크 등록 |
| | | this.issueUserService.insertIssueUser(issueAssigneeMaps); |
| | | } |
| | | } |
| | | |
| | | // 이슈 리스크 벌크 등록 |
| | | private void bulkInsertIssueRisk(List<IssueForm> issueForms, Workspace workspace) { |
| | | List<Map<String, Long>> issueRiskMaps = Lists.newArrayList(); |
| | | for (IssueForm issueForm : issueForms) { |
| | | Map<String, Long> issueRiskMap = new HashMap<>(); |
| | | issueRiskMap.put("issueId", issueForm.getId()); |
| | | issueRiskMap.put("changeAssigneeCount", 0L); |
| | | issueRiskMap.put("changeIssueStatusCount", 0L); |
| | | issueRiskMap.put("workspaceId", workspace.getId()); |
| | | issueRiskMap.put("issueStatusIds", issueForm.getIssueStatusId()); |
| | | issueRiskMap.put("registerId", this.webAppUtil.getLoginId()); |
| | | issueRiskMaps.add(issueRiskMap); |
| | | } |
| | | |
| | | if (issueRiskMaps.size() > 0) { |
| | | // 이슈 리스크 벌크 등록 |
| | | this.issueMapper.insertIssueRiskBatch(issueRiskMaps); |
| | | } |
| | | } |
| | | |
| | | // 이슈 사용자 정의 필드 선택 값 벌크 등록 |
| | | private void bulkInsertIssueCustomFieldValue(List<IssueForm> issueForms, Map<String, Long> issueTypeCustomFieldMaps) { |
| | | List<Map<String, Object>> issueCustomFieldValueMaps = Lists.newArrayList(); |
| | | |
| | | for (IssueForm issueForm : issueForms) { |
| | | for (Map<String, Object> issueCustomField : issueForm.getIssueCustomFields()) { |
| | | String findKey = issueForm.getIssueTypeId().toString() + MapUtil.getString(issueCustomField, "customFieldId"); |
| | | |
| | | // 이슈 타입 + 사용자 정의 필드 연결정보가 없다면 저장하지 않는다. |
| | | if (issueTypeCustomFieldMaps.get(findKey) == null) { |
| | | continue; |
| | | } |
| | | |
| | | issueCustomField.put("issueTypeCustomFieldId", issueTypeCustomFieldMaps.get(findKey)); |
| | | issueCustomField.put("issueId", issueForm.getId()); |
| | | issueCustomField.put("registerId", this.webAppUtil.getLoginId()); |
| | | issueCustomFieldValueMaps.add(issueCustomField); |
| | | } |
| | | } |
| | | |
| | | if (issueCustomFieldValueMaps.size() > 0) { |
| | | this.issueMapper.insertIssueCustomFieldValueBatch(issueCustomFieldValueMaps); |
| | | } |
| | | } |
| | | |
| | | // 이슈의 주요 속성을 map 에 저장하여 엑셀 import 에서 지정한 대상(이슈 속성)을 빠르게 찾을 수 있게 한다. |
| | | private void IssueAttributeMapToList(Map<String, Project> projectMaps, Map<String, IssueType> issueTypeMaps, Map<String, Priority> priorityMaps, Map<String, Severity> severityMaps, |
| | | Map<String, Object> userMaps, Map<String, CustomField> customFieldMaps, Map<Long, Long> issueNumberMaps, Map<String, Long> issueTypeCustomFieldMaps, Map<String, IssueStatus> issueStatusReadyMaps) { |
| | | // 프로젝트 키로 바로 찾을 수 있게 준비 |
| | | List<Project> projects = this.projectService.findByWorkspaceId(); |
| | | List<Long> projectIds = Lists.newArrayList(); |
| | | |
| | | for (Project project : projects) { |
| | | projectIds.add(project.getId()); |
| | | // 해당 프로젝트에서 생성되는 다음 이슈 번호를 생성해온다. |
| | | issueNumberMaps.put(project.getId(), this.issueNumberGeneratorService.generateIssueNumber(project)); |
| | | projectMaps.put(project.getProjectKey(), project); |
| | | |
| | | for (IssueTypeCustomField issueTypeCustomField : project.getIssueTypeCustomFields()) { |
| | | // 빠르게 찾기 위해 이슈 타입 아이디 + 사용자 정의 필드 아이디를 키로 한다. |
| | | String makeKey = issueTypeCustomField.getIssueType().getId().toString() + issueTypeCustomField.getCustomField().getId().toString(); |
| | | issueTypeCustomFieldMaps.put(makeKey, issueTypeCustomField.getId()); |
| | | } |
| | | |
| | | // 프로젝트에 참여하는 사용자 정보 |
| | | List<Map<String, Object>> users = this.userService.findProjectMember(project); |
| | | Map<String, Object> userMap = new HashMap<>(); |
| | | // 사용자 정보를 Map 에 저장 |
| | | for (Map<String, Object> user : users) { |
| | | userMap.put(CommonUtil.decryptAES128(MapUtil.getString(user, "account")), MapUtil.getLong(user, "userId")); |
| | | } |
| | | |
| | | userMaps.put(project.getProjectKey(), userMap); |
| | | } |
| | | |
| | | // 이슈 유형을 바로 찾을 수 있게 준비 |
| | | List<IssueType> issueTypes = this.issueTypeService.findByWorkspaceId(); |
| | | for (IssueType issueType : issueTypes) { |
| | | issueTypeMaps.put(issueType.getName(), issueType); |
| | | |
| | | IssueStatus issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow()); |
| | | issueStatusReadyMaps.put(issueType.getId().toString(), issueStatus); |
| | | } |
| | | |
| | | // 우선순위를 바로 찾을 수 있게 준비 |
| | | List<Priority> priorities = this.priorityService.findByWorkspaceId(); |
| | | for (Priority priority : priorities) { |
| | | priorityMaps.put(priority.getName(), priority); |
| | | } |
| | | |
| | | // 중요도를 바로 찾을 수 있게 준비 |
| | | List<Severity> severities = this.severityService.findByWorkspaceId(); |
| | | for (Severity severity : severities) { |
| | | severityMaps.put(severity.getName(), severity); |
| | | } |
| | | |
| | | // 사용자 정의 필드를 바로 찾을 수 있게 준비 |
| | | List<CustomField> customFields = this.customFieldService.findByWorkspaceId(); |
| | | for (CustomField customField : customFields) { |
| | | customFieldMaps.put(customField.getName(), customField); |
| | | } |
| | | } |
| | | |
| | | // 엑셀 필드에 있는 정보를 이슈 form 으로 옮긴다. |
| | | private IssueForm setIssueFormToExcelField(Row row, int rowIndex, Map<String, IssueStatus> issueStatusReadyMaps, Map<String, Project> projectMaps, Map<String, IssueType> issueTypeMaps, Map<String, |
| | | Priority> priorityMaps, Map<String, Severity> severityMaps, Map<String, Object> userMaps, Map<String, CustomField> customFieldMaps, Map<Long, Long> issueNumberMaps, List<String> headers) { |
| | | IssueForm issueForm = new IssueForm(); |
| | | issueForm.setRegisterId(this.webAppUtil.getLoginId()); |
| | | Project project = null; |
| | | |
| | | // 제목, 내용, 프로젝트 키, 이슈 타입, 우선순위, 중요도, 담당자, 시작일, 종료일, 사용자 정의 필드 |
| | | for (int cellIndex = 0; cellIndex < headers.size(); cellIndex++) { |
| | | Cell cell = row.getCell(cellIndex); |
| | | switch (cellIndex) { |
| | | case 0: |
| | | // 이슈 제목을 IssueForm 에 저장한다. |
| | | this.setIssueFormTitle(cell, issueForm, rowIndex); |
| | | break; |
| | | |
| | | case 1: // 내용 |
| | | if (cell != null) { |
| | | issueForm.setDescription(CommonUtil.convertExcelStringToCell(cell)); |
| | | } else { |
| | | // null 입력 방지 |
| | | issueForm.setDescription(""); |
| | | } |
| | | |
| | | break; |
| | | |
| | | case 2: // 프로젝트 키와 이슈 번호 |
| | | project = this.setIssueFormProjectKeyAndIssueNumber(cell, issueForm, projectMaps, issueNumberMaps, rowIndex); |
| | | break; |
| | | |
| | | case 3: |
| | | // 이슈 타입을 IssueForm 에 저장한다. |
| | | this.setIssueFormIssueType(cell, issueTypeMaps, issueForm, rowIndex); |
| | | // 이슈 타입에 연결된 워크플로우의 상태 속성 '대기' 인 상태를 issueForm 에 저장한다. |
| | | this.setIssueFormIssueStatus(issueStatusReadyMaps, issueForm, rowIndex); |
| | | break; |
| | | |
| | | case 4: |
| | | // 우선순위를 IssueForm 에 저장한다. |
| | | this.setIssueFormPriority(cell, priorityMaps, issueForm, rowIndex); |
| | | break; |
| | | |
| | | case 5: |
| | | // 중요도를 IssueForm 에 저장한다. |
| | | this.setIssueFormSeverity(cell, severityMaps, issueForm, rowIndex); |
| | | break; |
| | | case 6: |
| | | // 담당자를 IssueForm 에 저장한다. |
| | | this.setIssueFormAssignee(cell, userMaps, issueForm, project); |
| | | break; |
| | | case 7: |
| | | // 시작일을 IssueForm 에 저장한다. |
| | | this.setIssueFormPeriod(cell, issueForm, true, rowIndex); |
| | | break; |
| | | case 8: |
| | | // 종료일을 IssueForm 에 저장한다. |
| | | this.setIssueFormPeriod(cell, issueForm, false, rowIndex); |
| | | break; |
| | | default: |
| | | // 8번 이상부터는 사용자 정의 필드. 사용자 정의 필드 정보를 IssueForm 에 저장한다. |
| | | this.setIssueFormCustomFieldValue(cell, customFieldMaps, issueForm, headers.get(cellIndex), rowIndex); |
| | | } |
| | | } |
| | | |
| | | return issueForm; |
| | | } |
| | | |
| | | // 이슈 제목을 IssueForm 에 저장한다. |
| | | private void setIssueFormTitle(Cell cell, IssueForm issueForm, int rowIndex) { |
| | | if (cell == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_ISSUE_TITLE_IS_NULL, rowIndex)); |
| | | } |
| | | |
| | | String title = CommonUtil.convertExcelStringToCell(cell); |
| | | |
| | | // 제목 유효성 체크 |
| | | this.verifyTitle(title); |
| | | issueForm.setTitle(title); |
| | | } |
| | | |
| | | // 프로젝트 키, 이슈 고유 번호, 담당자를 IssueForm 에 저장한다. |
| | | private Project setIssueFormProjectKeyAndIssueNumber(Cell cell, IssueForm issueForm, Map<String, Project> projectMaps, Map<Long, Long> issueNumberMaps, int rowIndex) { |
| | | // 프로젝트 아이디를 IssueForm 에 저장한다. |
| | | Project project = this.setIssueFormProject(cell, projectMaps, issueForm, rowIndex); |
| | | |
| | | // 이슈 고유 번호를 IssueForm 에 저장한다. |
| | | this.setIssueFormIssueNumber(issueForm, issueNumberMaps, project, rowIndex); |
| | | |
| | | return project; |
| | | } |
| | | |
| | | // 프로젝트 아이디를 IssueForm 에 저장한다. |
| | | private Project setIssueFormProject(Cell cell, Map<String, Project> projectMaps, IssueForm issueForm, int rowIndex) { |
| | | if (cell == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PROJECT_KEY_IS_NULL, rowIndex)); |
| | | } |
| | | |
| | | Project project = projectMaps.get(CommonUtil.convertExcelStringToCell(cell).toUpperCase()); |
| | | |
| | | if (project == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PROJECT_NOT_EXIST, rowIndex)); |
| | | } |
| | | |
| | | issueForm.setProjectId(project.getId()); |
| | | |
| | | return project; |
| | | } |
| | | |
| | | // 이슈 고유 번호를 IssueForm 에 저장한다. |
| | | private void setIssueFormIssueNumber(IssueForm issueForm, Map<Long, Long> issueNumberMaps, Project project, int rowIndex) { |
| | | // 이슈 고유 번호 |
| | | Long issueNumber = issueNumberMaps.get(project.getId()); |
| | | |
| | | if (issueNumber == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NUMBER_NOT_EXIST, rowIndex)); |
| | | } |
| | | |
| | | issueForm.setIssueNumber(issueNumber); |
| | | issueNumberMaps.put(project.getId(), ++issueNumber); // 이슈 번호를 1씩 증가 시킨다. |
| | | } |
| | | |
| | | // 이슈 타입을 IssueForm 에 저장한다. |
| | | private void setIssueFormIssueType(Cell cell, Map<String, IssueType> issueTypeMaps, IssueForm issueForm, int rowIndex) { |
| | | if (cell == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_ISSUE_TYPE_IS_NULL, rowIndex)); |
| | | } |
| | | |
| | | IssueType issueType = issueTypeMaps.get(CommonUtil.convertExcelStringToCell(cell)); |
| | | |
| | | if (issueType == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_ISSUE_TYPE_NOT_EXIST, rowIndex)); |
| | | } |
| | | |
| | | issueForm.setIssueTypeId(issueType.getId()); |
| | | } |
| | | |
| | | // 이슈 타입에 연결된 워크플로우의 상태 속성 '대기' 인 상태를 issueForm 에 저장한다. |
| | | private void setIssueFormIssueStatus(Map<String, IssueStatus> issueStatusReadyMaps, IssueForm issueForm, int rowIndex) { |
| | | IssueStatus issueStatus = issueStatusReadyMaps.get(issueForm.getIssueTypeId().toString()); |
| | | |
| | | if (issueStatus == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_ISSUE_STATUS_READY_NOT_EXIST, rowIndex)); |
| | | } |
| | | |
| | | issueForm.setIssueStatusId(issueStatus.getId()); |
| | | } |
| | | |
| | | // 우선순위를 IssueForm 에 저장한다. |
| | | private void setIssueFormPriority(Cell cell, Map<String, Priority> priorityMaps, IssueForm issueForm, int rowIndex) { |
| | | if (cell == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PRIORITY_IS_NULL, rowIndex)); |
| | | } |
| | | |
| | | Priority priority = priorityMaps.get(CommonUtil.convertExcelStringToCell(cell)); |
| | | |
| | | if (priority == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PRIORITY_NOT_EXIST, rowIndex)); |
| | | } |
| | | |
| | | issueForm.setPriorityId(priority.getId()); |
| | | } |
| | | |
| | | // 중요도를 IssueForm 에 저장한다. |
| | | private void setIssueFormSeverity(Cell cell, Map<String, Severity> severityMaps, IssueForm issueForm, int rowIndex) { |
| | | if (cell == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_SEVERITY_IS_NULL, rowIndex)); |
| | | } |
| | | |
| | | Severity severity = severityMaps.get(CommonUtil.convertExcelStringToCell(cell)); |
| | | |
| | | if (severity == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_SEVERITY_NOT_EXIST, rowIndex)); |
| | | } |
| | | |
| | | issueForm.setSeverityId(severity.getId()); |
| | | } |
| | | |
| | | // 담당자를 IssueForm 에 저장한다. |
| | | private void setIssueFormAssignee(Cell cell, Map<String, Object> userMaps, IssueForm issueForm, Project project) { |
| | | if (cell != null) { |
| | | String[] splitAssignee = CommonUtil.convertExcelStringToCell(cell).split("#"); |
| | | Map<String, Object> userMap = (Map<String, Object>) MapUtil.getObject(userMaps, project.getProjectKey()); |
| | | |
| | | List<Long> userIds = Lists.newArrayList(); |
| | | |
| | | for (String account : splitAssignee) { |
| | | if (MapUtil.getLong(userMap, account) != null) { |
| | | userIds.add(MapUtil.getLong(userMap, account)); |
| | | } |
| | | } |
| | | |
| | | issueForm.setUserIds(userIds); |
| | | } |
| | | } |
| | | |
| | | // 시작일, 종료일을 IssueForm 에 저장한다. |
| | | private void setIssueFormPeriod(Cell cell, IssueForm issueForm, Boolean checkStartDate, int rowIndex) { |
| | | if (cell != null && !cell.toString().equals("")) { |
| | | |
| | | Date startDate; |
| | | |
| | | try { |
| | | startDate = cell.getDateCellValue(); |
| | | } catch (Exception e) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PERIOD_NOT_VALIDITY_EMPTY, rowIndex)); |
| | | } |
| | | |
| | | if (checkStartDate) { |
| | | issueForm.setStartDate(DateUtil.convertDateToStr(startDate, "yyyy-MM-dd")); |
| | | } else { |
| | | issueForm.setCompleteDate(DateUtil.convertDateToStr(startDate, "yyyy-MM-dd")); |
| | | |
| | | try { |
| | | // 날짜 유효성 체크 |
| | | this.checkStartCompleteDate(issueForm.getStartDate(), issueForm.getCompleteDate()); |
| | | } catch (OwlRuntimeException e) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PERIOD_NOT_VALIDITY, rowIndex)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 사용자 정의 필드 정보를 IssueForm 에 저장한다. |
| | | private void setIssueFormCustomFieldValue(Cell cell, Map<String, CustomField> customFieldMaps, IssueForm issueForm, String customFieldName, int rowIndex) { |
| | | if (cell != null) { |
| | | String cellValue = CommonUtil.convertExcelStringToCell(cell); |
| | | Map<String, Object> issueCustomFieldMap = new HashMap<>(); |
| | | CustomField customField = customFieldMaps.get(customFieldName); |
| | | |
| | | if (customField == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_HEADER_CUSTOM_FIELD_NOT_EXIST, rowIndex)); |
| | | } |
| | | // 사용자 정의 필드 값이 공백이면 중지 |
| | | if (StringUtils.isEmpty(cellValue)) { |
| | | return; |
| | | } |
| | | |
| | | boolean validity = false; |
| | | |
| | | switch (customField.getCustomFieldType()) { |
| | | case INPUT: |
| | | if (cellValue.length() > 100) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_TEXT_TYPE_MAX_LENGTH_OUT)); |
| | | } |
| | | |
| | | issueCustomFieldMap.put("customFieldId", customField.getId()); |
| | | issueCustomFieldMap.put("useValue", cellValue); |
| | | issueForm.addIssueCustomFields(issueCustomFieldMap); |
| | | break; |
| | | case SINGLE_SELECT: |
| | | // 값 유효성 체크 |
| | | for (CustomFieldValue customFieldValue : customField.getCustomFieldValues()) { |
| | | if (customFieldValue.getValue().equals(cellValue)) { |
| | | validity = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!validity) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY, rowIndex)); |
| | | } |
| | | |
| | | issueCustomFieldMap.put("customFieldId", customField.getId()); |
| | | issueCustomFieldMap.put("useValue", cellValue); |
| | | issueForm.addIssueCustomFields(issueCustomFieldMap); |
| | | |
| | | break; |
| | | case MULTI_SELECT: |
| | | // 값 유효성 체크 |
| | | String[] useValues = cellValue.split("#"); |
| | | // 해, 달 |
| | | for (String useValue : useValues) { |
| | | for (CustomFieldValue customFieldValue : customField.getCustomFieldValues()) { |
| | | |
| | | if (customFieldValue.getValue().equals(useValue)) { |
| | | validity = true; |
| | | Map<String, Object> multiValueMap = new HashMap<>(); |
| | | multiValueMap.put("customFieldId", customField.getId()); |
| | | multiValueMap.put("useValue", useValue); |
| | | issueForm.addIssueCustomFields(multiValueMap); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | if (!validity) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY, rowIndex)); |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 프로젝트에 있는 모든 이슈 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Long> findByProjectId(Long projectId) { |
| | | List<Map<String, Object>> issueMaps = this.issueMapper.findByProjectId(projectId); |
| | | List<Long> issueIds = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> issueMap : issueMaps) { |
| | | Long issueId = MapUtil.getLong(issueMap, "id"); |
| | | if (issueId != null) { |
| | | issueIds.add(issueId); |
| | | } |
| | | } |
| | | |
| | | return issueIds; |
| | | } |
| | | |
| | | // 이슈를 대상자들에게 메일로 발송한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void sendIssueEmail(IssueForm issueForm) { |
| | | if (issueForm.getSendEmails().size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SEND_USER)); |
| | | } |
| | | |
| | | Issue issue = this.getIssue(issueForm.getId()); |
| | | |
| | | Map<String, Object> issueMap = new HashMap<>(); |
| | | // 이슈 정보를 이메일 전송에 사용하기 위해 Map 형태로 변환한다. |
| | | this.makeIssueMapToIssue(issue, issueMap); |
| | | // 발신자 표시 |
| | | UserVo toUser = this.webAppUtil.getLoginUser(); |
| | | issueMap.put("toUser", toUser.getName() + "(" + CommonUtil.decryptAES128(toUser.getAccount()) + ")"); |
| | | |
| | | // 이슈 링크 |
| | | String projectKey = issue.getProject().getProjectKey(); |
| | | Long IssueNumber = issue.getIssueNumber(); |
| | | String link = this.configuration.getEmailSendUrl() + "/#/issues/issueList?projectKey=" + projectKey + "&issueNumber=" + IssueNumber.toString(); |
| | | |
| | | issueMap.put("issueLink", link); |
| | | issueMap.put("projectLink", link); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_ANOTHER_USER_SEND_EMAIL)); |
| | | |
| | | this.systemEmailService.directEmail(issueForm.getSendEmails().toArray(new String[issueForm.getSendEmails().size()]), EmailType.ISSUE_SEND, issueMap, null); |
| | | } |
| | | |
| | | // 예약 발생 이슈를 실행한다 |
| | | @Override |
| | | @Transactional |
| | | public void reservationIssue() { |
| | | List<IssueReservation> issueReservations = this.issueReservationService.findByIssueReservationTypeNotNull(); |
| | | |
| | | Calendar calendar = Calendar.getInstance(); |
| | | int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); |
| | | int month = calendar.get(Calendar.MONTH) + 1; |
| | | int date = calendar.get(Calendar.DATE); |
| | | |
| | | for (IssueReservation issueReservation : issueReservations) { |
| | | switch (issueReservation.getIssueReservationType()) { |
| | | case DAY: |
| | | // 이슈를 다시 생성 상태로 변경시킨다. |
| | | this.occurReservationIssue(issueReservation.getIssue()); |
| | | break; |
| | | case WEEK: |
| | | if (dayOfWeek == Integer.parseInt(issueReservation.getReservation())) { |
| | | // 이슈를 다시 생성 상태로 변경시킨다. |
| | | this.occurReservationIssue(issueReservation.getIssue()); |
| | | } |
| | | |
| | | break; |
| | | case MONTH: |
| | | if (date == Integer.parseInt(issueReservation.getReservation())) { |
| | | // 이슈를 다시 생성 상태로 변경시킨다. |
| | | this.occurReservationIssue(issueReservation.getIssue()); |
| | | } |
| | | |
| | | break; |
| | | case YEAR: |
| | | String[] reservations = issueReservation.getReservation().split("-"); |
| | | |
| | | if (reservations.length > 1) { |
| | | if ((Integer.parseInt(reservations[0]) == month) && Integer.parseInt(reservations[1]) == date) { |
| | | // 이슈를 다시 생성 상태로 변경시킨다. |
| | | this.occurReservationIssue(issueReservation.getIssue()); |
| | | } |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈를 다시 생성 상태로 변경시킨다. |
| | | private void occurReservationIssue(Issue issue) { |
| | | if (!issue.getIssueStatus().getIssueStatusType().equals(IssueStatusType.READY)) { |
| | | // 이슈를 생성 상태로 변경시킨다. |
| | | IssueStatus issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issue.getIssueType().getWorkflow()); |
| | | |
| | | if (issueStatus != null) { |
| | | StringBuilder detectIssueChange = new StringBuilder(); |
| | | // 예약 발생으로 이슈 상태 변경된 정보를 기록한다. |
| | | this.issueHistoryService.detectReservationIssueStatus(issue, detectIssueChange, issueStatus); |
| | | issue.setIssueStatus(issueStatus); |
| | | this.issueRepository.saveAndFlush(issue); |
| | | // 이슈 상태 변경 정보를 이력으로 남긴다. |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.MODIFY, detectIssueChange.toString()); |
| | | // 이슈 버전 생성 |
| | | this.issueVersionService.addIssueVersion(issue); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Autowired |
| | | private ProjectMapper projectMapper; |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Map<String, Object> findTask(IssueCondition taskCondition) { |
| | | |
| | | StopWatch serviceStart = new StopWatch(); |
| | | serviceStart.start(); |
| | | ProjectCondition projectCondition = new ProjectCondition(this.webAppUtil.getLoginUser().getLastProjectId(), this.webAppUtil.getLoginId()); |
| | | List<Map<String, Object>> checkProjectRole = this.projectMapper.checkIncludeProject(projectCondition); |
| | | |
| | | if (checkProjectRole.size() < 1) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_INCLUDE_USER)); |
| | | } |
| | | |
| | | // 이중으로 역할 체크를 해서 참여하지 않은 사용자가 해당 프로젝트에 접근 못하도록 한다. |
| | | taskCondition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | // List<Map<String, Object>> results = this.taskMapper.find(taskCondition); |
| | | List<Map<String, Object>> results = this.issueMapper.find(taskCondition); |
| | | |
| | | serviceStart.stop(); |
| | | long executeTime = serviceStart.getTime(); |
| | | |
| | | Map<String, Object> tasks = new HashMap<>(); |
| | | // 워크플로우 상태 id 를 키로 만든다. |
| | | for (Long workflowStatusId : taskCondition.getStatusIds()) { |
| | | tasks.put(workflowStatusId.toString(), Lists.newArrayList()); |
| | | } |
| | | |
| | | Map<String, Object> taskUserSave = new HashMap<>(); |
| | | // 전체 task_id를 모은다. |
| | | for (Map<String, Object> result : results) { |
| | | Long taskId = MapUtil.getLong(result, "id"); |
| | | taskCondition.addIssueIds(taskId.toString()); |
| | | // 각 task_id 별로 사용자 정보를 저장할 공간을 미리 확보한다. |
| | | taskUserSave.put(taskId.toString(), Lists.newArrayList()); |
| | | } |
| | | |
| | | List<Map<String, Object>> taskUsers = Lists.newArrayList(); |
| | | // task 가 하나도 없을 경우에는 조회를 하지 않는다. |
| | | if (!taskCondition.getIssueIds().isEmpty()) { |
| | | taskUsers = this.issueMapper.getAllTaskUser(taskCondition); |
| | | } |
| | | |
| | | // task_id 에 매칭되는 담당자 정보를 준비한다. |
| | | for (Map<String, Object> taskUser : taskUsers) { |
| | | Long taskId = MapUtil.getLong(taskUser, "taskId"); |
| | | List<UserVo> userVos = (List<UserVo>)taskUserSave.get(taskId.toString()); |
| | | userVos.add(ConvertUtil.convertMapToClass(taskUser, UserVo.class)); |
| | | } |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | IssueVo taskVo = ConvertUtil.convertMapToClass(result, IssueVo.class); |
| | | |
| | | // 중요도 셋팅 |
| | | if (MapUtil.getLong(result, "priorityId") != null) { |
| | | PriorityVo priorityVo = new PriorityVo(); |
| | | priorityVo.setId(MapUtil.getLong(result, "priorityId")); |
| | | priorityVo.setName(MapUtil.getString(result, "priorityName")); |
| | | priorityVo.setColor(MapUtil.getString(result, "priorityColor")); |
| | | taskVo.setPriorityVo(priorityVo); |
| | | } |
| | | |
| | | // 워크플로우 상태 셋팅 |
| | | if (MapUtil.getLong(result, "workflowStatusId") != null) { |
| | | WorkflowStatusVo workflowStatusVo = new WorkflowStatusVo(); |
| | | workflowStatusVo.setId(MapUtil.getLong(result, "workflowStatusId")); |
| | | workflowStatusVo.setName(MapUtil.getString(result, "workflowStatusName")); |
| | | workflowStatusVo.setColor(MapUtil.getString(result, "workflowStatusColor")); |
| | | taskVo.setWorkflowStatusVo(workflowStatusVo); |
| | | } |
| | | |
| | | // 담당자 셋팅 |
| | | List<UserVo> userVos = (List<UserVo>)taskUserSave.get(taskVo.getId().toString()); |
| | | taskVo.setUserVos(userVos); |
| | | |
| | | List<IssueVo> taskVos = (List<IssueVo>)tasks.get(MapUtil.getString(result, "workflowStatusId")); |
| | | taskVos.add(taskVo); |
| | | tasks.put(MapUtil.getString(result, "workflowStatusId"), taskVos); |
| | | } |
| | | |
| | | /*serviceStart.stop(); |
| | | long executeTime = serviceStart.getTime();*/ |
| | | |
| | | return tasks; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.common.ExcelConditionCheck; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.IssueStatusType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.IssueStatusMapper; |
| | | import kr.wisestone.owl.repository.IssueStatusRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.condition.IssueStatusCondition; |
| | | import kr.wisestone.owl.web.form.IssueStatusForm; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class IssueStatusServiceImpl extends AbstractServiceImpl<IssueStatus, Long, JpaRepository<IssueStatus, Long>> implements IssueStatusService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueStatusServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueStatusRepository issueStatusRepository; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private WorkflowTransitionService workflowTransitionService; |
| | | |
| | | @Autowired |
| | | private IssueTypeService issueTypeService; |
| | | |
| | | @Autowired |
| | | private IssueStatusMapper issueStatusMapper; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | @Autowired |
| | | private ExcelConditionCheck excelConditionCheck; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueStatus, Long> getRepository() { |
| | | return this.issueStatusRepository; |
| | | } |
| | | |
| | | // 워크스페이스 생성시 생성되는 이슈 상태 - 프로젝트 유형에 따라 생성되는 이슈 상태가 달라진다. |
| | | @Override |
| | | @Transactional |
| | | public List<IssueStatus> addDefaultIssueStatus(Workspace workspace) { |
| | | List<IssueStatus> issueStatuses = Lists.newArrayList(); |
| | | issueStatuses.add(new IssueStatus(workspace, this.messageAccessor.message("common.create"), Boolean.TRUE, "#665fff", IssueStatusType.READY, 1L)); // 생성 |
| | | issueStatuses.add(new IssueStatus(workspace, this.messageAccessor.message("common.progress"), Boolean.TRUE, "#98c220", IssueStatusType.OPEN, 2L)); // 진행 |
| | | issueStatuses.add(new IssueStatus(workspace, this.messageAccessor.message("common.reProgress"), Boolean.TRUE, "#c940ea", IssueStatusType.OPEN, 3L)); // 재진행 |
| | | issueStatuses.add(new IssueStatus(workspace, this.messageAccessor.message("common.check"), Boolean.TRUE, "#febd35", IssueStatusType.OPEN, 4L)); // 확인 |
| | | issueStatuses.add(new IssueStatus(workspace, this.messageAccessor.message("common.end"), Boolean.TRUE, "#888888", IssueStatusType.CLOSE, 5L)); // 종료 |
| | | issueStatuses.add(new IssueStatus(workspace, this.messageAccessor.message("common.noApproval"), Boolean.TRUE, "#ff5f99", IssueStatusType.CLOSE, 6L)); // 승인 불가 |
| | | issueStatuses.add(new IssueStatus(workspace, this.messageAccessor.message("common.approval"), Boolean.TRUE, "#3598fe", IssueStatusType.CLOSE, 7L)); // 승인 |
| | | |
| | | return this.issueStatusRepository.saveAll(issueStatuses); |
| | | } |
| | | |
| | | // 워크스페이스에 존재하는 이슈 상태 조회 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueStatus> findByWorkspaceId(Long workspaceId) { |
| | | return this.issueStatusRepository.findByWorkspaceId(workspaceId); |
| | | } |
| | | |
| | | // 이슈 상태를 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public IssueStatus addIssueStatus(IssueStatusForm issueStatusForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | // 이름 유효성 체크 |
| | | this.verifyName(issueStatusForm.getName(), null); |
| | | // 색상 체크 |
| | | this.verifyColor(issueStatusForm.getColor()); |
| | | |
| | | IssueStatus issueStatus = ConvertUtil.copyProperties(issueStatusForm, IssueStatus.class, "issueStatusType"); |
| | | issueStatus.setIssueStatusType(IssueStatusType.valueOf(issueStatusForm.getIssueStatusType())); |
| | | issueStatus.setWorkspace(this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId())); |
| | | issueStatus.setPosition(0L); |
| | | |
| | | return this.issueStatusRepository.saveAndFlush(issueStatus); |
| | | } |
| | | |
| | | // 이름 유효성 체크 |
| | | private void verifyName(String name, Long id) { |
| | | if (StringUtils.isEmpty(name)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_NOT_NAME)); |
| | | } |
| | | |
| | | if (name.length() > 20) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_NAME_MAX_LENGTH_OUT)); |
| | | } |
| | | |
| | | IssueStatus issueStatus; |
| | | Long workspaceId = this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId(); |
| | | |
| | | if (id == null) { |
| | | issueStatus = this.issueStatusRepository.findByNameAndWorkspaceId(name, workspaceId); |
| | | } |
| | | else { |
| | | issueStatus = this.issueStatusRepository.findByNameAndWorkspaceIdAndIdNot(name, workspaceId, id); |
| | | } |
| | | |
| | | if (issueStatus != null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_USED_NAME)); |
| | | } |
| | | } |
| | | |
| | | // 색상 체크 |
| | | private void verifyColor(String color) { |
| | | if (StringUtils.isEmpty(color)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_NOT_COLOR)); |
| | | } |
| | | } |
| | | |
| | | // 이슈 상태 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueStatusVo> findIssueStatus(Map<String, Object> resJsonData, |
| | | IssueStatusCondition condition, Pageable pageable) { |
| | | |
| | | condition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | condition.setPageSize(pageable.getPageSize()); |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | |
| | | List<Map<String, Object>> results = this.issueStatusMapper.find(condition); |
| | | Long totalCount = this.issueStatusMapper.count(condition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | List<IssueStatusVo> issueStatusVos = ConvertUtil.convertListToListClass(results, IssueStatusVo.class); |
| | | |
| | | // 이슈 상태가 워크플로우에 사용되고 있는지 여부를 체크하고 이슈 상태 안에 사용되는 워크플로우 정보를 셋팅한다. |
| | | if (condition.getDeep() != null) { |
| | | this.setUseIssueStatusByWorkflow(issueStatusVos); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueStatusVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | return issueStatusVos; |
| | | } |
| | | |
| | | // 이슈 상태 목록을 조회한다 - 페이징 사용x 워크플로우 생성, 수정에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueStatusVo> findIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition condition) { |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | List<Map<String, Object>> results = this.issueStatusMapper.find(condition); |
| | | List<IssueStatusVo> issueStatusVos = ConvertUtil.convertListToListClass(results, IssueStatusVo.class); |
| | | // issueStatusType 별로 정렬 |
| | | Collections.sort(issueStatusVos); |
| | | // ready 상태가 앞으로 오도록 다시 정렬 |
| | | Collections.reverse(issueStatusVos); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueStatusVos); |
| | | return issueStatusVos; |
| | | } |
| | | |
| | | // 이슈 상태를 사용하고 있는 워크플로우 정보를 셋팅한다. |
| | | private void setUseIssueStatusByWorkflow(List<IssueStatusVo> issueStatusVos) { |
| | | for (IssueStatusVo issueStatusVo : issueStatusVos) { |
| | | Map<String, Object> workflows = new HashMap<>(); |
| | | IssueStatus issueStatus = this.getIssueStatus(issueStatusVo.getId()); |
| | | this.findUseIssueStatusByWorkflow(issueStatus.getSourceWorkflowTransitions().iterator(), workflows); |
| | | this.findUseIssueStatusByWorkflow(issueStatus.getTargetWorkflowTransitions().iterator(), workflows); |
| | | |
| | | for (String key : workflows.keySet()) { |
| | | issueStatusVo.addWorkflowVos((WorkflowVo) workflows.get(key)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 이슈 상태를 사용하고 있는 워크플로우를 찾는다. |
| | | private void findUseIssueStatusByWorkflow(Iterator<WorkflowTransition> iterator, Map<String, Object> workflows) { |
| | | while (iterator.hasNext()) { |
| | | WorkflowTransition workflowTransition = iterator.next(); |
| | | workflows.put(workflowTransition.getWorkflow().getId().toString(), ConvertUtil.copyProperties(workflowTransition.getWorkflow(), WorkflowVo.class)); |
| | | } |
| | | } |
| | | |
| | | // 이슈의 현재 상태에서 이동 가능한 다음 상태 정보 목록을 찾는다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void findNextIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition condition) { |
| | | IssueType issueType = this.issueTypeService.getIssueType(condition.getIssueTypeId()); |
| | | IssueStatus issueStatus = this.getIssueStatus(condition.getId()); |
| | | Workflow workflow = issueType.getWorkflow(); |
| | | |
| | | List<WorkflowTransitionVo> workflowTransitionVos = this.workflowTransitionService.findBySourceIssueStatusIdAndWorkflowId(issueStatus.getId(), workflow.getId()); |
| | | List<IssueStatusVo> issueStatusVos = Lists.newArrayList(); |
| | | |
| | | for (WorkflowTransitionVo workflowTransitionVo : workflowTransitionVos) { |
| | | IssueStatusVo issueStatusVo = new IssueStatusVo(); |
| | | issueStatusVo.setId(workflowTransitionVo.getTargetStatusId()); |
| | | issueStatusVo.setName(workflowTransitionVo.getTargetStatusName()); |
| | | issueStatusVos.add(issueStatusVo); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueStatusVos); |
| | | } |
| | | |
| | | |
| | | // 이슈 상태 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition issueStatusCondition) { |
| | | IssueStatusVo issueStatusVo = new IssueStatusVo(); |
| | | |
| | | if (issueStatusCondition.getId() != null) { |
| | | IssueStatus issueStatus = this.getIssueStatus(issueStatusCondition.getId()); |
| | | issueStatusVo = ConvertUtil.copyProperties(issueStatus, IssueStatusVo.class); |
| | | issueStatusVo.setIssueStatusType(issueStatus.getIssueStatusType().toString()); |
| | | |
| | | if (issueStatusCondition.getDeep().equals("01")) { |
| | | int useCount = issueStatus.getSourceWorkflowTransitions().size() + issueStatus.getTargetWorkflowTransitions().size(); |
| | | |
| | | if (useCount > 0) { |
| | | issueStatusVo.setUseYn(true); |
| | | } |
| | | } |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueStatusVo); |
| | | } |
| | | |
| | | // 이슈 상태 정보를 수정한다. |
| | | @Override |
| | | @Transactional |
| | | public IssueStatus modifyIssueStatus(IssueStatusForm issueStatusForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 이름 유효성 체크 |
| | | this.verifyName(issueStatusForm.getName(), issueStatusForm.getId()); |
| | | // 색상 체크 |
| | | this.verifyColor(issueStatusForm.getColor()); |
| | | |
| | | IssueStatus issueStatus = this.getIssueStatus(issueStatusForm.getId()); |
| | | ConvertUtil.copyProperties(issueStatusForm, issueStatus, "id", "issueStatusType"); |
| | | issueStatus.setIssueStatusType(IssueStatusType.valueOf(issueStatusForm.getIssueStatusType())); |
| | | |
| | | return this.issueStatusRepository.saveAndFlush(issueStatus); |
| | | } |
| | | |
| | | // 이슈 상태 아이디로 이슈 상태를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueStatus getIssueStatus(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | |
| | | IssueStatus issueStatus = this.findOne(id); |
| | | |
| | | if (issueStatus == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | |
| | | return issueStatus; |
| | | } |
| | | |
| | | // 이슈 상태를 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssueStatus(IssueStatusForm issueStatusForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | if (issueStatusForm.getRemoveIds().size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_REMOVE_NOT_SELECT)); |
| | | } |
| | | |
| | | for (Long issueStatusId : issueStatusForm.getRemoveIds()) { |
| | | this.removeIssueStatuses(issueStatusId); |
| | | } |
| | | |
| | | this.issueStatusRepository.flush(); |
| | | } |
| | | |
| | | private void removeIssueStatuses(Long issueStatusId) { |
| | | IssueStatus issueStatus = this.getIssueStatus(issueStatusId); |
| | | |
| | | // 삭제할 이슈 상태가 이슈 에서 사용되고 있는지 확인한다. |
| | | this.checkUseIssueStatus(issueStatus); |
| | | // 삭제할 이슈 상태가 워크플로우 에서 사용되고 있는지 확인한다. |
| | | this.checkUseWorkflow(issueStatus); |
| | | |
| | | // 기본으로 제공되는 이슈 상태는 삭제 금지 |
| | | if (issueStatus.getDefaultYn()) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.DEFAULT_ISSUE_STATUS_NOT_REMOVE)); |
| | | } |
| | | |
| | | this.issueStatusRepository.delete(issueStatus); |
| | | } |
| | | |
| | | // 삭제할 이슈 상태가 이슈 에서 사용되고 있는지 확인한다. |
| | | private void checkUseIssueStatus(IssueStatus issueStatus) { |
| | | // 이슈 유형을 사용하는 이슈 갯수를 조회한다. |
| | | long issueCount = this.issueService.countByIssueStatus(issueStatus.getId()); |
| | | |
| | | if (issueCount > 0) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_USE_ISSUES)); |
| | | } |
| | | } |
| | | |
| | | // 삭제할 이슈 상태가 워크플로우 에서 사용되고 있는지 확인한다. |
| | | private void checkUseWorkflow(IssueStatus issueStatus) { |
| | | List<IssueStatusVo> issueStatusVos = Lists.newArrayList(ConvertUtil.copyProperties(issueStatus, IssueStatusVo.class)); |
| | | // 이슈 상태를 사용하고 있는 워크플로우 정보를 셋팅한다. |
| | | this.setUseIssueStatusByWorkflow(issueStatusVos); |
| | | |
| | | for (IssueStatusVo issueStatusVo : issueStatusVos) { |
| | | if (issueStatusVo.getWorkflowVos().size() > 0) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_USE_WORKFLOW)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 워크플로우에 있는 이슈 상태를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueStatusVo> findByWorkflowId(Long workflowId) { |
| | | List<WorkflowTransition> workflowTransitions = this.workflowTransitionService.findByWorkflowId(workflowId); |
| | | |
| | | Map<String, Object> issueStatuses = new HashMap<>(); |
| | | List<IssueStatusVo> issueStatusVos = Lists.newArrayList(); |
| | | |
| | | for (WorkflowTransition workflowTransition : workflowTransitions) { |
| | | IssueStatus source = workflowTransition.getSourceIssueStatus(); |
| | | IssueStatus target = workflowTransition.getTargetIssueStatus(); |
| | | |
| | | // 대상 이슈 상태가 이미 저장되어 있는지 확인한다. - source 항목 |
| | | if (source != null) { |
| | | this.setIssueStatusLocation(issueStatuses, source, workflowTransition.getSourceX(), workflowTransition.getSourceY()); |
| | | } |
| | | |
| | | // 대상 이슈 상태가 이미 저장되어 있는지 확인한다. - target 항목 |
| | | if (target != null) { |
| | | this.setIssueStatusLocation(issueStatuses, target, workflowTransition.getTargetX(), workflowTransition.getTargetY()); |
| | | } |
| | | } |
| | | |
| | | Iterator<String> iterator = issueStatuses.keySet().iterator(); |
| | | |
| | | while (iterator.hasNext()) { |
| | | IssueStatusVo issueStatusVo = (IssueStatusVo) issueStatuses.get(iterator.next()); |
| | | issueStatusVo.setWorkflowTransitionVos(this.workflowTransitionService.findBySourceIssueStatusIdAndWorkflowId(issueStatusVo.getId(), workflowId)); |
| | | issueStatusVos.add(issueStatusVo); |
| | | } |
| | | |
| | | return issueStatusVos; |
| | | } |
| | | |
| | | |
| | | private void setIssueStatusLocation(Map<String, Object> issueStatuses, IssueStatus issueStatus, Long xLocation, Long yLocation) { |
| | | Object targetIssueStatus = MapUtil.getObject(issueStatuses, issueStatus.getId().toString()); |
| | | |
| | | if (targetIssueStatus == null) { |
| | | IssueStatusVo issueStatusVo = ConvertUtil.copyProperties(issueStatus, IssueStatusVo.class); |
| | | issueStatusVo.setxLocation(xLocation); |
| | | issueStatusVo.setyLocation(yLocation); |
| | | issueStatusVo.setIssueStatusType(issueStatus.getIssueStatusType().toString()); |
| | | |
| | | issueStatuses.put(issueStatus.getId().toString(), issueStatusVo); |
| | | } |
| | | } |
| | | |
| | | // 이슈 상태 속성이 대기인 이슈 상태를 가져온다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueStatus findByIssueStatusTypeIsReady(Workflow workflow) { |
| | | List<IssueStatusVo> issueStatusVos = this.findByWorkflowId(workflow.getId()); |
| | | IssueStatus issueStatus = null; |
| | | |
| | | for (IssueStatusVo issueStatusVo : issueStatusVos) { |
| | | if (IssueStatusType.READY.equals(IssueStatusType.valueOf(issueStatusVo.getIssueStatusType()))) { |
| | | issueStatus = this.getIssueStatus(issueStatusVo.getId()); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (issueStatus == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.READY_ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | |
| | | return issueStatus; |
| | | } |
| | | |
| | | // 이슈 상태를 변경할 때 선택한 이슈 상태로 변경할 수 있는지 확인한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void checkNextIssueStatus(Issue issue, IssueStatus nextIssueStatus) { |
| | | Workflow workflow = issue.getIssueType().getWorkflow(); |
| | | boolean passNextIssueStatus = false; |
| | | |
| | | List<WorkflowTransitionVo> workflowTransitionVos = this.workflowTransitionService.findBySourceIssueStatusIdAndWorkflowId(issue.getIssueStatus().getId(), workflow.getId()); |
| | | |
| | | for (WorkflowTransitionVo workflowTransitionVo : workflowTransitionVos) { |
| | | if (workflowTransitionVo.getTargetStatusId().equals(nextIssueStatus.getId())) { |
| | | passNextIssueStatus = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!passNextIssueStatus) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_STATUS_CHANGE_NOT_TARGET)); |
| | | } |
| | | } |
| | | |
| | | // 이슈 상태 목록을 엑셀로 다운로드 한다. |
| | | @Override |
| | | @Transactional |
| | | public ModelAndView downloadExcel(HttpServletRequest request, Model model) { |
| | | // 사용 공간에서 로그인한 사용자가 비활성인지 확인하고 비활성일 경우 엑셀 다운로드를 금지한다. |
| | | ModelAndView modelAndView = this.workspaceService.checkUseExcelDownload(model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | Map<String, Object> conditions = new HashMap<>(); |
| | | // 엑셀 다운로드에 필요한 검색 조건 정보를 추출하고 검색 조건 추출에 오류가 발생하면 경고를 표시해준다. |
| | | modelAndView = this.excelConditionCheck.checkCondition(conditions, request, model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | IssueStatusCondition issueStatusCondition = IssueStatusCondition.make(conditions); |
| | | issueStatusCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | List<Map<String, Object>> results = this.issueStatusMapper.find(issueStatusCondition); |
| | | List<IssueStatusVo> issueStatusVos = ConvertUtil.convertListToListClass(results, IssueStatusVo.class); |
| | | |
| | | // 이슈 상태가 워크플로우에 사용되고 있는지 여부를 체크하고 이슈 상태 안에 사용되는 워크플로우 정보를 셋팅한다. |
| | | if (issueStatusCondition.getDeep() != null) { |
| | | this.setUseIssueStatusByWorkflow(issueStatusVos); |
| | | } |
| | | |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.setFileName(this.messageAccessor.message("common.issueStatusList")); // 이슈 상태 목록 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("name", this.messageAccessor.message("common.issueStatus"), 10, ExportExcelAttrVo.ALIGN_LEFT)); // 이슈 상태 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("issueStatusType", this.messageAccessor.message("common.statusProperties"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 상태 속성 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("color", this.messageAccessor.message("common.color"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 색상 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("workflowNames", this.messageAccessor.message("common.workflow"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 워크플로우 |
| | | // 엑셀에 넣을 데이터 - issueStatusVos 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | excelInfo.setDatas(this.convertExcelViewToIssueStatusVos(issueStatusVos)); |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | // IssueStatusVo 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | private List<Map<String, String>> convertExcelViewToIssueStatusVos(List<IssueStatusVo> issueStatusVos) { |
| | | List<Map<String, String>> results = Lists.newArrayList(); |
| | | |
| | | for (IssueStatusVo issueStatusVo : issueStatusVos) { |
| | | Map<String, String> result = new HashMap<>(); |
| | | |
| | | result.put("name", issueStatusVo.getName()); |
| | | |
| | | String issueStatusType = ""; |
| | | switch (issueStatusVo.getIssueStatusType()) { |
| | | case "READY": |
| | | issueStatusType = this.messageAccessor.message("common.wait"); // 대기 |
| | | break; |
| | | case "OPEN": |
| | | issueStatusType = this.messageAccessor.message("common.progress"); // 진행 |
| | | break; |
| | | case "CLOSE": |
| | | issueStatusType = this.messageAccessor.message("common.end"); // 종료 |
| | | break; |
| | | } |
| | | |
| | | result.put("issueStatusType", issueStatusType); |
| | | result.put("color", issueStatusVo.getColor()); |
| | | |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | |
| | | for (WorkflowVo workflowVo : issueStatusVo.getWorkflowVos()) { |
| | | stringBuilder.append(workflowVo.getName()); |
| | | stringBuilder.append("\n"); |
| | | } |
| | | |
| | | result.put("workflowNames", stringBuilder.toString()); |
| | | results.add(result); |
| | | } |
| | | |
| | | return results; |
| | | } |
| | | |
| | | // 여러건의 이슈의 현재 상태에서 이동 가능한 다음 상태 정보 목록을 찾는다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void findNextMultiIssueStatus(Map<String, Object> resJsonData, IssueStatusCondition issueStatusCondition) { |
| | | List<IssueStatusVo> issueStatusVos = Lists.newArrayList(); |
| | | int count = 0; |
| | | |
| | | // 워크플로우에서 이동 가능한 상태 추출 |
| | | for (Long issueId : issueStatusCondition.getIssueIds()) { |
| | | Issue issue = this.issueService.getIssue(issueId); |
| | | Workflow workflow = issue.getIssueType().getWorkflow(); |
| | | List<WorkflowTransitionVo> workflowTransitionVos = this.workflowTransitionService.findBySourceIssueStatusIdAndWorkflowId(issue.getIssueStatus().getId(), workflow.getId()); |
| | | |
| | | List<IssueStatusVo> tempIssueStatusVos = Lists.newArrayList(); |
| | | |
| | | for (WorkflowTransitionVo workflowTransitionVo : workflowTransitionVos) { |
| | | // 첫번째 이슈에서 이동 가능한 상태 정보를 저장한다. |
| | | if (count < 1) { |
| | | IssueStatusVo issueStatusVo = new IssueStatusVo(workflowTransitionVo.getTargetStatusId(), workflowTransitionVo.getTargetStatusName()); |
| | | issueStatusVos.add(issueStatusVo); |
| | | } |
| | | else { |
| | | // 두번째 이슈부터 첫번째 이슈에서 이동 가능했던 상태 중 없는 대상을 찾는다. |
| | | for (IssueStatusVo issueStatusVo : issueStatusVos) { |
| | | if (issueStatusVo.getId().equals(workflowTransitionVo.getTargetStatusId())) { |
| | | tempIssueStatusVos.add(issueStatusVo); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (count > 0) { |
| | | // 비교한 후 존재하는 이슈 상태만 저장 |
| | | issueStatusVos = tempIssueStatusVos; |
| | | } |
| | | |
| | | count++; |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueStatusVos); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.domain.IssueTableConfig; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.repository.IssueTableConfigRepository; |
| | | import kr.wisestone.owl.service.IssueTableConfigService; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueTableConfigServiceImpl extends AbstractServiceImpl<IssueTableConfig, Long, JpaRepository<IssueTableConfig, Long>> implements IssueTableConfigService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueTableConfigServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueTableConfigRepository issueTableConfigRepository; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueTableConfig, Long> getRepository() { |
| | | return this.issueTableConfigRepository; |
| | | } |
| | | |
| | | // 이슈 테이블 컬럼 설정 정보를 저장한다. |
| | | @Override |
| | | @Transactional |
| | | public IssueTableConfig addIssueTableConfig(Map<String, Object> params) { |
| | | String issueTableConfigs = MapUtil.getString(params, "issueTableConfigs"); |
| | | // 해당 업무 공간에서 사용자의 이슈 목록 테이블 컬럼 설정을 조회한다. |
| | | IssueTableConfig saveIssueTableConfig = this.findByUserIdAndWorkspaceId(); |
| | | |
| | | // 아직 테이블 컬럼 설정을 하지 않았을 경우 |
| | | if (saveIssueTableConfig == null) { |
| | | IssueTableConfig issueTableConfig = new IssueTableConfig(); |
| | | Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | User user = this.userService.getUser(this.webAppUtil.getLoginId()); |
| | | issueTableConfig.setWorkspace(workspace); |
| | | issueTableConfig.setUser(user); |
| | | issueTableConfig.setIssueTableConfigs(issueTableConfigs); |
| | | return this.issueTableConfigRepository.saveAndFlush(issueTableConfig); |
| | | } |
| | | else { |
| | | saveIssueTableConfig.setIssueTableConfigs(issueTableConfigs); |
| | | return this.issueTableConfigRepository.saveAndFlush(saveIssueTableConfig); |
| | | } |
| | | } |
| | | |
| | | // 해당 업무 공간에서 사용자의 이슈 테이블 설정을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueTableConfig findByUserIdAndWorkspaceId() { |
| | | return this.issueTableConfigRepository.findByUserIdAndWorkspaceId(this.webAppUtil.getLoginId(), |
| | | this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | |
| | | // 저장된 이슈 테이블 설정을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailIssueTableConfig(Map<String, Object> resJsonData) { |
| | | // 해당 업무 공간에서 사용자의 이슈 검색 조건을 조회한다. |
| | | IssueTableConfig issueTableConfig = this.findByUserIdAndWorkspaceId(); |
| | | |
| | | if (issueTableConfig != null) { |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueTableConfig.getIssueTableConfigs()); |
| | | } |
| | | else { |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, ""); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.repository.IssueTypeCustomFieldRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.CustomFieldValueVo; |
| | | import kr.wisestone.owl.vo.CustomFieldVo; |
| | | import kr.wisestone.owl.vo.IssueTypeCustomFieldVo; |
| | | import kr.wisestone.owl.web.condition.IssueTypeCustomFieldCondition; |
| | | import kr.wisestone.owl.web.form.IssueTypeCustomFieldForm; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueTypeCustomFieldServiceImpl extends AbstractServiceImpl<IssueTypeCustomField, Long, JpaRepository<IssueTypeCustomField, Long>> implements IssueTypeCustomFieldService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueTypeCustomFieldServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueTypeCustomFieldRepository issueTypeCustomFieldRepository; |
| | | |
| | | @Autowired |
| | | private ProjectService projectService; |
| | | |
| | | @Autowired |
| | | private IssueTypeService issueTypeService; |
| | | |
| | | @Autowired |
| | | private CustomFieldService customFieldService; |
| | | |
| | | @Autowired |
| | | private IssueCustomFieldValueService issueCustomFieldValueService; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueTypeCustomField, Long> getRepository() { |
| | | return this.issueTypeCustomFieldRepository; |
| | | } |
| | | |
| | | // 프로젝트에서 사용하는 필드 정보를 업데이트한다. |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueTypeCustomFields(IssueTypeCustomFieldForm issueTypeCustomFieldForm) { |
| | | List<IssueTypeCustomField> issueTypeCustomFields = Lists.newArrayList(); |
| | | Project project = this.projectService.getProject(issueTypeCustomFieldForm.getProjectId()); |
| | | IssueType issueType = this.issueTypeService.getIssueType(issueTypeCustomFieldForm.getIssueTypeId()); |
| | | List<IssueTypeCustomField> saveIssueTypeCustomFields = this.issueTypeCustomFieldRepository.findByProjectIdAndIssueTypeId(project.getId(), issueType.getId()); |
| | | |
| | | List<Long> addIssueTypeCustomFields = Lists.newArrayList(); |
| | | List<IssueTypeCustomField> removeIssueTypeCustomFields = Lists.newArrayList(); |
| | | |
| | | // 저장해야할 대상 추출 |
| | | for (Map<String, Object> map : issueTypeCustomFieldForm.getRelationCustomFields()) { |
| | | Long customFieldId = MapUtil.getLong(map, "id"); |
| | | boolean exist = false; |
| | | |
| | | for (IssueTypeCustomField issueTypeCustomField : saveIssueTypeCustomFields) { |
| | | if (issueTypeCustomField.getCustomField().getId().equals(customFieldId)) { |
| | | exist = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!exist) { |
| | | addIssueTypeCustomFields.add(customFieldId); |
| | | } |
| | | } |
| | | |
| | | // 삭제 대상 추출 |
| | | for (IssueTypeCustomField issueTypeCustomField : saveIssueTypeCustomFields) { |
| | | boolean exist = false; |
| | | |
| | | for (Map<String, Object> map : issueTypeCustomFieldForm.getRelationCustomFields()) { |
| | | Long customFieldId = MapUtil.getLong(map, "id"); |
| | | |
| | | // 이미 저장되어 있는 대상은 따로 저장 |
| | | if (issueTypeCustomField.getCustomField().getId().equals(customFieldId)) { |
| | | exist = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!exist) { |
| | | removeIssueTypeCustomFields.add(issueTypeCustomField); |
| | | } |
| | | } |
| | | |
| | | // 이슈 타입 - 사용자 정의 필드 삭제 |
| | | if (removeIssueTypeCustomFields.size() > 0) { |
| | | for (IssueTypeCustomField issueTypeCustomField : removeIssueTypeCustomFields) { |
| | | // 이슈 - 사용자 정의 필드 값 삭제 |
| | | this.issueCustomFieldValueService.removeIssueCustomFieldValue(issueTypeCustomField.getId()); |
| | | } |
| | | |
| | | this.issueTypeCustomFieldRepository.deleteAll(removeIssueTypeCustomFields); |
| | | } |
| | | |
| | | for (Long customFieldId : addIssueTypeCustomFields) { |
| | | CustomField customField = this.customFieldService.getCustomField(customFieldId); |
| | | IssueTypeCustomField issueTypeCustomField = new IssueTypeCustomField(project, issueType, customField, IssueTypeCustomField.FIELD_OPTION_N); |
| | | issueTypeCustomFields.add(issueTypeCustomField); |
| | | } |
| | | |
| | | // 이슈 타입 - 사용자 정의 필드 정보 연결 |
| | | if (issueTypeCustomFields.size() > 0) { |
| | | this.issueTypeCustomFieldRepository.saveAll(issueTypeCustomFields); |
| | | this.issueTypeCustomFieldRepository.flush(); |
| | | } |
| | | |
| | | // 사용자 정의 필드가 이슈에서 표시되는 순서를 설정한다. |
| | | this.setIssueTypeCustomFieldPosition(project.getId(), issueType.getId(), issueTypeCustomFieldForm.getRelationCustomFields()); |
| | | |
| | | } |
| | | |
| | | // 사용자 정의 필드가 이슈에서 표시되는 순서를 설정한다. |
| | | private void setIssueTypeCustomFieldPosition(Long projectId, Long issueTypeId, List<Map<String, Object>> relationCustomFields) { |
| | | |
| | | List<IssueTypeCustomField> saveIssueTypeCustomFields = this.issueTypeCustomFieldRepository.findByProjectIdAndIssueTypeId(projectId, issueTypeId); |
| | | |
| | | int count = 1; |
| | | |
| | | for (Map<String, Object> relationCustomField : relationCustomFields) { |
| | | Long customFieldId = MapUtil.getLong(relationCustomField, "id"); |
| | | |
| | | if (customFieldId != null) { |
| | | for (IssueTypeCustomField issueTypeCustomField : saveIssueTypeCustomFields) { |
| | | if (issueTypeCustomField.getCustomField().getId().equals(customFieldId)) { |
| | | issueTypeCustomField.setPosition(count); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | count++; |
| | | } |
| | | |
| | | if (saveIssueTypeCustomFields.size() > 0) { |
| | | this.issueTypeCustomFieldRepository.saveAll(saveIssueTypeCustomFields); |
| | | this.issueTypeCustomFieldRepository.flush(); |
| | | } |
| | | } |
| | | |
| | | // 프로젝트에서 사용하는 전체 필드 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueTypeCustomFieldVo> findIssueTypeCustomField(Map<String, Object> resJsonData, IssueTypeCustomFieldCondition condition) { |
| | | Project project = this.projectService.getProject(condition.getProjectId()); |
| | | IssueType issueType = this.issueTypeService.getIssueType(condition.getIssueTypeId()); |
| | | |
| | | List<IssueTypeCustomField> issueTypeCustomFields = this.issueTypeCustomFieldRepository.findByProjectIdAndIssueTypeIdOrderByPosition(project.getId(), issueType.getId()); |
| | | List<IssueTypeCustomFieldVo> issueTypeCustomFieldVos = Lists.newArrayList(); |
| | | |
| | | for (IssueTypeCustomField issueTypeCustomField : issueTypeCustomFields) { |
| | | IssueTypeCustomFieldVo issueTypeCustomFieldVo = new IssueTypeCustomFieldVo(); |
| | | CustomFieldVo customFieldVo = ConvertUtil.copyProperties(issueTypeCustomField.getCustomField(), CustomFieldVo.class); |
| | | customFieldVo.setCustomFieldValueVos(ConvertUtil.convertObjectsToClasses(issueTypeCustomField.getCustomField().getCustomFieldValues(), CustomFieldValueVo.class)); |
| | | customFieldVo.setCustomFieldType(issueTypeCustomField.getCustomField().getCustomFieldType().toString()); |
| | | issueTypeCustomFieldVo.setCustomFieldVo(customFieldVo); |
| | | issueTypeCustomFieldVo.setFieldOption(issueTypeCustomField.getFieldOption()); |
| | | issueTypeCustomFieldVo.setChecked(issueTypeCustomField.getFieldOption().equals(IssueTypeCustomField.FIELD_OPTION_Y)); // 화면에서 옵션 체크되도록 checked 에 값 셋팅 |
| | | issueTypeCustomFieldVos.add(issueTypeCustomFieldVo); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueTypeCustomFieldVos); |
| | | |
| | | return issueTypeCustomFieldVos; |
| | | } |
| | | |
| | | // 이슈 excel template download 에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueTypeCustomField> findByProjectIdAndIssueTypeId(Long projectId, Long issueTypeId) { |
| | | return this.issueTypeCustomFieldRepository.findByProjectIdAndIssueTypeId(projectId, issueTypeId); |
| | | } |
| | | |
| | | // 이슈 add / modify 에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueTypeCustomField findByProjectIdAndIssueTypeIdAndCustomFieldId(Long projectId, Long issueTypeId, Long customFieldId) { |
| | | return this.issueTypeCustomFieldRepository.findByProjectIdAndIssueTypeIdAndCustomFieldId(projectId, issueTypeId, customFieldId); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.common.ExcelConditionCheck; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.IssueTypeMapper; |
| | | import kr.wisestone.owl.repository.IssueTypeRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.condition.IssueTypeCondition; |
| | | import kr.wisestone.owl.web.form.IssueTypeForm; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueTypeServiceImpl extends AbstractServiceImpl<IssueType, Long, JpaRepository<IssueType, Long>> implements IssueTypeService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueTypeServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueTypeRepository issueTypeRepository; |
| | | |
| | | @Autowired |
| | | private WorkflowService workflowService; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private IssueTypeMapper issueTypeMapper; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | @Autowired |
| | | private ExcelConditionCheck excelConditionCheck; |
| | | |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueType, Long> getRepository() { |
| | | return this.issueTypeRepository; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void addDefaultIssueType(Workspace workspace, List<ProjectType> projectTypes) { |
| | | for (ProjectType projectType : projectTypes) { |
| | | List<IssueType> issueTypes = Lists.newArrayList(); |
| | | Workflow workflow = this.workflowService.findByWorkspaceIdAndProjectType(workspace.getId(), projectType); |
| | | |
| | | switch (projectType) { |
| | | case BTS_PROJECT: |
| | | issueTypes.add(new IssueType(workspace, workflow, this.messageAccessor.message("common.bug"), "", "#ff5f99")); // 버그 |
| | | issueTypes.add(new IssueType(workspace, workflow, this.messageAccessor.message("common.improvement"), "", "#3598fe")); // 개선 |
| | | break; |
| | | |
| | | case RMS_PROJECT: |
| | | issueTypes.add(new IssueType(workspace, workflow, this.messageAccessor.message("common.requirement"), "", "#3bcde2")); // 요구 사항 |
| | | break; |
| | | |
| | | case TCM_PROJECT: |
| | | issueTypes.add(new IssueType(workspace, workflow, this.messageAccessor.message("common.testcase"), "", "#008ca7")); // 테스트 케이스, 실행 순서, 전제 조건, 기대 결과 |
| | | break; |
| | | } |
| | | |
| | | this.issueTypeRepository.saveAll(issueTypes); |
| | | } |
| | | } |
| | | |
| | | // 이슈 유형을 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public IssueType addIssueType(IssueTypeForm issueTypeForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 이름 유효성 체크 |
| | | this.verifyName(issueTypeForm.getName(), null); |
| | | // 색상 체크 |
| | | this.verifyColor(issueTypeForm.getColor()); |
| | | |
| | | IssueType issueType = ConvertUtil.copyProperties(issueTypeForm, IssueType.class); |
| | | Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | issueType.setWorkspace(workspace); |
| | | Workflow workflow = this.workflowService.getWorkflow(issueTypeForm.getWorkflowId()); |
| | | issueType.setWorkflow(workflow); |
| | | |
| | | return this.issueTypeRepository.saveAndFlush(issueType); |
| | | } |
| | | |
| | | // 이름 유효성 체크 |
| | | private void verifyName(String name, Long id) { |
| | | if (StringUtils.isEmpty(name)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_NOT_NAME)); |
| | | } |
| | | |
| | | if (name.length() > 15) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_NAME_MAX_LENGTH_OUT)); |
| | | } |
| | | |
| | | IssueType issueType; |
| | | Long workspaceId = this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId(); |
| | | |
| | | if (id == null) { |
| | | issueType = this.issueTypeRepository.findByNameAndWorkspaceId(name, workspaceId); |
| | | } else { |
| | | issueType = this.issueTypeRepository.findByNameAndWorkspaceIdAndIdNot(name, workspaceId, id); |
| | | } |
| | | |
| | | if (issueType != null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_USED_NAME)); |
| | | } |
| | | } |
| | | |
| | | // 색상 체크 |
| | | private void verifyColor(String color) { |
| | | if (StringUtils.isEmpty(color)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_NOT_COLOR)); |
| | | } |
| | | } |
| | | |
| | | // 이슈 유형 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueTypeVo> findIssueType(Map<String, Object> resJsonData, |
| | | IssueTypeCondition condition, Pageable pageable) { |
| | | |
| | | condition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | condition.setPageSize(pageable.getPageSize()); |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | List<Map<String, Object>> results = this.issueTypeMapper.find(condition); |
| | | Long totalCount = this.issueTypeMapper.count(condition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | List<IssueTypeVo> issueTypeVos = ConvertUtil.convertListToListClass(results, IssueTypeVo.class); |
| | | |
| | | // 이슈 유형에 연결된 워크플로우 정보를 셋팅한다. |
| | | if (condition.getDeep() != null) { |
| | | this.setUseIssueTypeByWorkflow(issueTypeVos); |
| | | } |
| | | |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueTypeVos); |
| | | |
| | | return issueTypeVos; |
| | | } |
| | | |
| | | // 이슈 유형에 연결된 워크플로우 정보를 셋팅한다. |
| | | private void setUseIssueTypeByWorkflow(List<IssueTypeVo> issueTypeVos) { |
| | | for (IssueTypeVo issueTypeVo : issueTypeVos) { |
| | | IssueType issueType = this.getIssueType(issueTypeVo.getId()); |
| | | issueTypeVo.setWorkflowVo(ConvertUtil.copyProperties(issueType.getWorkflow(), WorkflowVo.class)); |
| | | } |
| | | } |
| | | |
| | | // 이슈 유형 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailIssueType(Map<String, Object> resJsonData, IssueTypeCondition issueTypeCondition) { |
| | | IssueTypeVo issueTypeVo = new IssueTypeVo(); |
| | | |
| | | if (issueTypeCondition.getId() != null) { |
| | | IssueType issueType = this.getIssueType(issueTypeCondition.getId()); |
| | | issueTypeVo = ConvertUtil.copyProperties(issueType, IssueTypeVo.class); |
| | | |
| | | switch (issueTypeCondition.getDeep()) { |
| | | case "01": // 워크플로우 정보를 가져온다. |
| | | issueTypeVo.setWorkflowVo(ConvertUtil.copyProperties(issueType.getWorkflow(), WorkflowVo.class)); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueTypeVo); |
| | | } |
| | | |
| | | // 이슈 유형을 수정한다. |
| | | @Override |
| | | @Transactional |
| | | public IssueType modifyIssueType(IssueTypeForm issueTypeForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | IssueType issueType = this.getIssueType(issueTypeForm.getId()); |
| | | // 이름 유효성 체크 |
| | | this.verifyName(issueTypeForm.getName(), issueTypeForm.getId()); |
| | | // 색상 체크 |
| | | this.verifyColor(issueTypeForm.getColor()); |
| | | |
| | | Workflow workflow = this.workflowService.getWorkflow(issueTypeForm.getWorkflowId()); |
| | | // 워크플로우 변경 체크 |
| | | this.checkWorkflowChange(issueType.getWorkflow(), workflow, issueType); |
| | | |
| | | ConvertUtil.copyProperties(issueTypeForm, issueType, "id", "issueTypeType"); |
| | | issueType.setWorkflow(workflow); |
| | | |
| | | this.issueTypeRepository.saveAndFlush(issueType); |
| | | |
| | | return issueType; |
| | | } |
| | | |
| | | // 워크플로우가 변경되었는지 확인하고 변경되었을 경우 이슈 상태가 없는 이슈는 '생성' 인 이슈 상태로 이동한다. |
| | | private void checkWorkflowChange(Workflow oldWorkflow, Workflow newWorkflow, IssueType issueType) { |
| | | if (!oldWorkflow.getId().equals(newWorkflow.getId())) { |
| | | // 이슈 유형에서 워크플로우가 변경되었을 때 해당 워크플로우에 현재 이슈 상태가 존재하지 않으면 대기(생성) 로 변경한다. |
| | | this.issueService.changeWorkflows(newWorkflow, issueType); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public IssueType getIssueType(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_NOT_EXIST)); |
| | | } |
| | | |
| | | IssueType issueType = this.findOne(id); |
| | | |
| | | if (issueType == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_NOT_EXIST)); |
| | | } |
| | | |
| | | return issueType; |
| | | } |
| | | |
| | | // 이슈 유형을 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssueTypes(IssueTypeForm issueTypeForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | if (issueTypeForm.getRemoveIds().size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_REMOVE_NOT_SELECT)); |
| | | } |
| | | |
| | | for (Long projectId : issueTypeForm.getRemoveIds()) { |
| | | this.removeIssueTypes(projectId); |
| | | } |
| | | |
| | | this.issueTypeRepository.flush(); |
| | | } |
| | | |
| | | private void removeIssueTypes(Long issueTypeId) { |
| | | IssueType issueType = this.getIssueType(issueTypeId); |
| | | // 삭제할 이슈 유형이 사용되고 있는지 확인한다. |
| | | this.checkUseIssueType(issueType); |
| | | this.issueTypeRepository.delete(issueType); |
| | | } |
| | | |
| | | // 삭제할 이슈 유형이 사용되고 있는지 확인한다. |
| | | private void checkUseIssueType(IssueType issueType) { |
| | | // 이슈 유형을 사용하는 이슈 갯수를 조회한다. |
| | | Long issueCount = this.issueService.countByIssueTypeId(issueType.getId()); |
| | | |
| | | if (issueCount > 0) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_TYPE_USE_ISSUES)); |
| | | } |
| | | } |
| | | |
| | | // 워크스페이스에 있는 모든 이슈 유형을 조회한다. 이슈 엑셀 import 에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<IssueType> findByWorkspaceId() { |
| | | return this.issueTypeRepository.findByWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | |
| | | // 이슈 타입 필드 목록을 엑셀로 다운로드 한다. |
| | | @Override |
| | | @Transactional |
| | | public ModelAndView downloadExcel(HttpServletRequest request, Model model) { |
| | | // 사용 공간에서 로그인한 사용자가 비활성인지 확인하고 비활성일 경우 엑셀 다운로드를 금지한다. |
| | | ModelAndView modelAndView = this.workspaceService.checkUseExcelDownload(model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | Map<String, Object> conditions = new HashMap<>(); |
| | | // 엑셀 다운로드에 필요한 검색 조건 정보를 추출하고 검색 조건 추출에 오류가 발생하면 경고를 표시해준다. |
| | | modelAndView = this.excelConditionCheck.checkCondition(conditions, request, model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | IssueTypeCondition issueTypeCondition = IssueTypeCondition.make(conditions); |
| | | issueTypeCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | List<Map<String, Object>> results = this.issueTypeMapper.find(issueTypeCondition); |
| | | List<IssueTypeVo> issueTypeVos = ConvertUtil.convertListToListClass(results, IssueTypeVo.class); |
| | | |
| | | // 이슈 유형에 연결된 워크플로우 정보를 셋팅한다. |
| | | if (issueTypeCondition.getDeep() != null) { |
| | | this.setUseIssueTypeByWorkflow(issueTypeVos); |
| | | } |
| | | |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.setFileName(this.messageAccessor.message("common.issueTypeList")); // 이슈 타입 목록 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("name", this.messageAccessor.message("common.issueType"), 15, ExportExcelAttrVo.ALIGN_LEFT)); // 이슈 타입 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("color", this.messageAccessor.message("common.color"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 색상 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("workflowName", this.messageAccessor.message("common.workflow"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 워크플로우 |
| | | // 엑셀에 넣을 데이터 |
| | | excelInfo.setDatas(this.convertExcelViewToIssueTypeVos(issueTypeVos)); |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | // IssueTypeVo 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | private List<Map<String, String>> convertExcelViewToIssueTypeVos(List<IssueTypeVo> issueTypeVos) { |
| | | List<Map<String, String>> results = Lists.newArrayList(); |
| | | |
| | | for (IssueTypeVo issueTypeVo : issueTypeVos) { |
| | | Map<String, String> result = new HashMap<>(); |
| | | result.put("name", issueTypeVo.getName()); |
| | | result.put("color", issueTypeVo.getColor()); |
| | | result.put("workflowName", issueTypeVo.getWorkflowVo().getName()); |
| | | results.add(result); |
| | | } |
| | | |
| | | return results; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.mapper.IssueUserMapper; |
| | | import kr.wisestone.owl.repository.IssueUserRepository; |
| | | import kr.wisestone.owl.service.IssueUserService; |
| | | import kr.wisestone.owl.service.ProjectService; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueUserServiceImpl extends AbstractServiceImpl<IssueUser, Long, JpaRepository<IssueUser, Long>> implements IssueUserService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueUserServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueUserRepository issueUserRepository; |
| | | |
| | | @Autowired |
| | | private IssueUserMapper issueUserMapper; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueUser, Long> getRepository() { |
| | | return this.issueUserRepository; |
| | | } |
| | | |
| | | // 이슈 담당자를 변경한다. |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueUser(Issue issue, Workspace workspace, List<Long> userIds) { |
| | | List<Long> oldUserIds = Lists.newArrayList(); |
| | | |
| | | // 이전 담당자 |
| | | for (IssueUser issueUser : issue.getIssueUsers()) { |
| | | oldUserIds.add(issueUser.getUser().getId()); |
| | | } |
| | | |
| | | List<Long> newUserIds = CommonUtil.searchChangeList(oldUserIds, userIds); // 추가해야할 사용자를 찾는다. |
| | | List<Long> removeUserIds = CommonUtil.searchChangeList(userIds, oldUserIds); // 삭제해야할 사용자를 찾는다. |
| | | |
| | | if (removeUserIds.size() > 0) { |
| | | Map<String, Object> removeIssueAssigneeMap = new HashMap<>(); |
| | | removeIssueAssigneeMap.put("issueId", issue.getId()); |
| | | removeIssueAssigneeMap.put("userIds", removeUserIds); |
| | | |
| | | // 담당자 삭제 |
| | | this.issueUserMapper.deleteIssueUserByIssueIdAndMultiUserId(removeIssueAssigneeMap); |
| | | } |
| | | |
| | | if (newUserIds.size() > 0) { |
| | | List<Map<String, Long>> addIssueAssigneeMaps = Lists.newArrayList(); |
| | | |
| | | for (Long userId : newUserIds) { |
| | | Map<String, Long> issueAssigneeMap = new HashMap<>(); |
| | | issueAssigneeMap.put("userId", userId); |
| | | issueAssigneeMap.put("issueId", issue.getId()); |
| | | issueAssigneeMap.put("workspaceId", workspace.getId()); |
| | | issueAssigneeMap.put("registerId", this.webAppUtil.getLoginId()); |
| | | addIssueAssigneeMaps.add(issueAssigneeMap); |
| | | } |
| | | |
| | | // 담당자 추가 |
| | | this.issueUserMapper.insertIssueUser(addIssueAssigneeMaps); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // 이슈 담당자 찾기 |
| | | @Override |
| | | @Transactional |
| | | public List<IssueUser> find(Issue issue) { |
| | | return this.issueUserRepository.findByIssueId(issue.getId()); |
| | | } |
| | | |
| | | // 이슈 담당자 벌크 등록 |
| | | @Override |
| | | @Transactional |
| | | public void insertIssueUser(List<Map<String, Long>> issueAssigneeMaps) { |
| | | // 이슈 담당자 벌크 등록 |
| | | this.issueUserMapper.insertIssueUser(issueAssigneeMaps); |
| | | } |
| | | |
| | | // 이슈 담당자에서 제외한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeIssueUser(Long projectId, List<Long> excludeUserIds) { |
| | | |
| | | for (Long userId : excludeUserIds) { |
| | | Map<String, Object> issueUserMap = new HashMap<>(); |
| | | issueUserMap.put("userId", userId); |
| | | issueUserMap.put("projectId", projectId); |
| | | |
| | | List<Map<String, Object>> results = this.issueUserMapper.findByUserIdAndProjectId(issueUserMap); |
| | | |
| | | if (results.size() > 0) { |
| | | List<Long> issueIds = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | Long id = MapUtil.getLong(result, "id"); |
| | | |
| | | if (id != null) { |
| | | issueIds.add(id); |
| | | } |
| | | } |
| | | |
| | | if (issueIds.size() > 0) { |
| | | Map<String, Object> removeIssueAssigneeMap = new HashMap<>(); |
| | | removeIssueAssigneeMap.put("userId", userId); |
| | | removeIssueAssigneeMap.put("issueIds", issueIds); |
| | | this.issueUserMapper.deleteIssueUserByUserIdAndMultiIssueId(removeIssueAssigneeMap); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import com.google.gson.Gson; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueVersion; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.repository.IssueVersionRepository; |
| | | import kr.wisestone.owl.service.IssueService; |
| | | import kr.wisestone.owl.service.IssueVersionService; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.IssueVersionVo; |
| | | import kr.wisestone.owl.vo.IssueVo; |
| | | import kr.wisestone.owl.web.condition.IssueVersionCondition; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class IssueVersionServiceImpl extends AbstractServiceImpl<IssueVersion, Long, JpaRepository<IssueVersion, Long>> implements IssueVersionService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(IssueVersionServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IssueVersionRepository issueVersionRepository; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Override |
| | | protected JpaRepository<IssueVersion, Long> getRepository() { |
| | | return this.issueVersionRepository; |
| | | } |
| | | |
| | | // 이슈 버전 생성 |
| | | @Override |
| | | @Transactional |
| | | public void addIssueVersion(Issue issue) { |
| | | IssueVo issueVo = ConvertUtil.copyProperties(issue, IssueVo.class); |
| | | this.issueService.setIssueDetail(issueVo, issue); // 이슈 상세 정보를 셋팅한다. |
| | | |
| | | List<IssueVersion> issueVersions = this.issueVersionRepository.findByIssueId(issueVo.getId()); |
| | | |
| | | Gson gson = new Gson(); |
| | | String content = gson.toJson(issueVo); |
| | | IssueVersion issueVersion = new IssueVersion(issue, issue.getProject(), issue.getProject().getWorkspace(), content); |
| | | |
| | | if (issueVersions.size() > 0) { |
| | | IssueVersion prevIssueVersion = issueVersions.get(issueVersions.size() - 1); |
| | | issueVersion.setVersion(prevIssueVersion.getVersion() + 1); |
| | | } |
| | | else { |
| | | issueVersion.setVersion(1); |
| | | } |
| | | |
| | | this.issueVersionRepository.saveAndFlush(issueVersion); |
| | | } |
| | | |
| | | // 이슈 버전 정보를 만들어서 Vo 로 변환한다. |
| | | private IssueVersionVo makeIssueVersionVo(IssueVersion issueVersion) { |
| | | IssueVersionVo issueVersionVo = ConvertUtil.copyProperties(issueVersion, IssueVersionVo.class); // 이전 버전 |
| | | Gson gson = new Gson(); |
| | | Map<String, Object> targetIssueVersionContent = (Map<String, Object>) gson.fromJson(issueVersionVo.getContent(), Object.class); |
| | | issueVersionVo.setContent(null); |
| | | issueVersionVo.setVersionHistory(targetIssueVersionContent); |
| | | User beforeModifyUser = this.userService.getUser(issueVersionVo.getModifyId()); |
| | | issueVersionVo.setModifyByName(beforeModifyUser.getName() + "(" + CommonUtil.decryptAES128(beforeModifyUser.getAccount()) + ")"); |
| | | |
| | | return issueVersionVo; |
| | | } |
| | | |
| | | // 선택한 버전과 그 다음 버전 정보를 Vo로 만들어 리턴한다. |
| | | private void makeTargetAndNextIssueVersion(IssueVersion targetIssueVersion, IssueVersion nextIssueVersion, List<IssueVersion> issueVersions, Map<String, Object> results) { |
| | | // 이슈 버전 정보를 만들어서 Vo 로 변환한다. |
| | | IssueVersionVo targetIssueVersionVo = this.makeIssueVersionVo(targetIssueVersion); |
| | | // 이슈 버전 정보를 만들어서 Vo 로 변환한다. |
| | | IssueVersionVo nextIssueVersionVo = this.makeIssueVersionVo(nextIssueVersion); |
| | | |
| | | results.put("targetIssueVersionVo", targetIssueVersionVo); |
| | | results.put("nextIssueVersionVo", nextIssueVersionVo); |
| | | |
| | | List<IssueVersionVo> issueVersionVos = ConvertUtil.convertObjectsToClasses(issueVersions, IssueVersionVo.class); |
| | | issueVersionVos.remove(issueVersionVos.size() - 1); |
| | | results.put("issueVersionList", issueVersionVos); |
| | | } |
| | | |
| | | |
| | | // 이슈 버전 정보 조회 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void find(Map<String, Object> resJsonData, IssueVersionCondition issueVersionCondition) { |
| | | List<IssueVersion> issueVersions = this.issueVersionRepository.findByIssueId(issueVersionCondition.getIssueId()); |
| | | |
| | | Map<String, Object> results = new HashMap<>(); |
| | | results.put("targetIssueVersionVo", null); |
| | | results.put("nextIssueVersionVo", null); |
| | | results.put("issueVersionList", Lists.newArrayList()); |
| | | |
| | | if (issueVersionCondition.getId() == null) { |
| | | if (issueVersions.size() > 1) { |
| | | IssueVersion targetIssueVersion = issueVersions.get(issueVersions.size() - 2); |
| | | IssueVersion nextIssueVersion = issueVersions.get(issueVersions.size() - 1); |
| | | // 선택한 버전과 그 다음 버전 정보를 Vo 로 만들어 리턴한다. |
| | | this.makeTargetAndNextIssueVersion(targetIssueVersion, nextIssueVersion, issueVersions, results); |
| | | } |
| | | } |
| | | else { |
| | | IssueVersion targetIssueVersion = null; // 선택한 버전 |
| | | IssueVersion nextIssueVersion = null; // 선택한 버전의 다음 버전 |
| | | |
| | | for (IssueVersion issueVersion : issueVersions) { |
| | | // 선택한 버전을 찾았으면 그 다음 버전을 찾는다. |
| | | if (targetIssueVersion != null) { |
| | | nextIssueVersion = issueVersion; |
| | | break; |
| | | } |
| | | |
| | | // 선택한 버전을 찾는다. |
| | | if (issueVersion.getId().equals(issueVersionCondition.getId())) { |
| | | targetIssueVersion = issueVersion; |
| | | } |
| | | } |
| | | |
| | | // 둘다 존재할 때만 버전 비교가 가능하다. |
| | | if (targetIssueVersion != null && nextIssueVersion != null) { |
| | | // 선택한 버전과 그 다음 버전 정보를 Vo 로 만들어 리턴한다. |
| | | this.makeTargetAndNextIssueVersion(targetIssueVersion, nextIssueVersion, issueVersions, results); |
| | | } |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, results); |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MngPermission; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.UserWorkspace; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.UserWorkspaceMapper; |
| | | import kr.wisestone.owl.repository.UserRepository; |
| | | import kr.wisestone.owl.repository.UserWorkspaceRepository; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.service.ManageUserService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.SecurityUtils; |
| | | import kr.wisestone.owl.vo.ResPage; |
| | | import kr.wisestone.owl.vo.ManageUserVo; |
| | | import kr.wisestone.owl.web.condition.UserWorkspaceCondition; |
| | | import kr.wisestone.owl.web.form.ManageUserForm; |
| | | import kr.wisestone.owl.web.form.UserWorkspaceForm; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.messaging.simp.SimpMessagingTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class ManageUserServiceImpl extends AbstractServiceImpl<UserWorkspace, Long, JpaRepository<UserWorkspace, Long>> implements ManageUserService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ManageUserServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private UserRepository userRepository; |
| | | |
| | | @Autowired |
| | | private UserWorkspaceRepository userWorkspaceRepository; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private UserWorkspaceMapper userWorkspaceMapper; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Override |
| | | protected JpaRepository<UserWorkspace, Long> getRepository() { |
| | | return this.userWorkspaceRepository; |
| | | } |
| | | |
| | | // 업무 공간에 참여/참여대기 하는 전체 사용자 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<ManageUserVo> findUserPermission(Map<String, Object> resJsonData, |
| | | UserWorkspaceCondition condition, Pageable pageable) { |
| | | |
| | | // 업무 공간를 가져온다. |
| | | Workspace primaryWorkspace = this.workspaceService.getPrimaryWorkspace(); |
| | | condition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | condition.setPageSize(pageable.getPageSize()); |
| | | condition.setWorkspaceId(primaryWorkspace.getId()); |
| | | condition.setAccount(CommonUtil.encryptAES128(condition.getAccount())); |
| | | |
| | | List<Map<String, Object>> results = this.userWorkspaceMapper.find(condition); |
| | | Long totalCount = this.userWorkspaceMapper.count(condition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | List<ManageUserVo> manageUserVos = ConvertUtil.convertListToListClass(results, ManageUserVo.class); |
| | | |
| | | for (ManageUserVo manageUserVo : manageUserVos) { |
| | | manageUserVo.setAccount(CommonUtil.decryptAES128(manageUserVo.getAccount())); |
| | | manageUserVo.setPermission(manageUserVo.getPermission()); |
| | | } |
| | | |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, manageUserVos); |
| | | |
| | | return manageUserVos; |
| | | } |
| | | |
| | | // 업무 공간에 연결된 사용자의 참여 상태를 변경한다. |
| | | @Override |
| | | @Transactional |
| | | public void modifyUserPermission(ManageUserForm manageUserForm) { |
| | | int newPermission = MngPermission.USER_PERMISSION_MNG_NONE; |
| | | |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermWorkSpace(), MngPermission.USER_PERMISSION_MNG_WORKSPACE); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermProjectSetting(), MngPermission.USER_PERMISSION_MNG_PROJECT); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermIssueSetting(), MngPermission.USER_PERMISSION_MNG_ISSUE_SETTING); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermUser(), MngPermission.USER_PERMISSION_MNG_USER); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermNotice(), MngPermission.USER_PERMISSION_MNG_NOTICE); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermFAQ(), MngPermission.USER_PERMISSION_MNG_FAQ); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermQnA(), MngPermission.USER_PERMISSION_MNG_QNA); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermEvent(), MngPermission.USER_PERMISSION_MNG_EVENT); |
| | | newPermission |= MngPermission.makePermission(manageUserForm.getPermGuide(), MngPermission.USER_PERMISSION_MNG_GUIDE); |
| | | |
| | | User user = userService.getUser(manageUserForm.getUserId()); |
| | | user.setPermission(newPermission); |
| | | |
| | | this.userRepository.saveAndFlush(user); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.config.kafka.KafkaSender; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.Notice; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.NoticeMapper; |
| | | import kr.wisestone.owl.repository.NoticeRepository; |
| | | import kr.wisestone.owl.service.NoticeService; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.NoticeVo; |
| | | import kr.wisestone.owl.vo.ResPage; |
| | | import kr.wisestone.owl.web.condition.NoticeCondition; |
| | | import kr.wisestone.owl.web.form.NoticeForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class NoticeServiceImpl extends AbstractServiceImpl<Notice, Long, JpaRepository<Notice, Long>> implements NoticeService { |
| | | |
| | | @Autowired |
| | | private NoticeRepository noticeRepository; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private KafkaSender kafkaSender; |
| | | |
| | | @Autowired |
| | | private NoticeMapper noticeMapper; |
| | | |
| | | @Override |
| | | protected JpaRepository<Notice, Long> getRepository() { |
| | | return this.noticeRepository; |
| | | } |
| | | |
| | | // 공지 사항 등록 |
| | | @Override |
| | | @Transactional |
| | | public Notice addNotice(NoticeForm noticeForm) { |
| | | // 공지사항 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(noticeForm.getTitle(), noticeForm.getDescription()); |
| | | |
| | | Notice notice = ConvertUtil.copyProperties(noticeForm, Notice.class); |
| | | |
| | | return this.noticeRepository.saveAndFlush(notice); |
| | | } |
| | | |
| | | // 공지사항 제목 및 내용 공백 체크 |
| | | private void verifyTitleAndDescription(String title, String description) { |
| | | if (StringUtils.isEmpty(title) || StringUtils.isEmpty(description)) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.NOTICE_EMPTY_CONTENT)); |
| | | } |
| | | } |
| | | |
| | | // 공지사항 조회 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<NoticeVo> findNotice(Map<String, Object> resJsonData, |
| | | NoticeCondition noticeCondition, Pageable pageable) { |
| | | |
| | | noticeCondition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | noticeCondition.setPageSize(pageable.getPageSize()); |
| | | noticeCondition.setTitle(noticeCondition.getTitle()); |
| | | |
| | | List<Map<String, Object>> results = this.noticeMapper.find(noticeCondition); |
| | | Long totalCount = this.noticeMapper.count(noticeCondition); |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | List<NoticeVo> noticeVos = ConvertUtil.convertListToListClass(results, NoticeVo.class); |
| | | |
| | | // 로그인 아이디 1 은 관리자 - 관리자만 수정 가능 |
| | | for (NoticeVo noticeVo : noticeVos) { |
| | | if (this.webAppUtil.getLoginId().equals(1L)) { |
| | | noticeVo.setModifyPermissionCheck(true); |
| | | } |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, noticeVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | return noticeVos; |
| | | } |
| | | |
| | | // 공지사항 수정 |
| | | @Override |
| | | @Transactional |
| | | public Notice modifyNotice(NoticeForm noticeForm) { |
| | | // 공지사항 제목 및 내용 공백 체크 |
| | | this.verifyTitleAndDescription(noticeForm.getTitle(), noticeForm.getDescription()); |
| | | |
| | | Notice notice = this.getNotice(noticeForm.getId()); |
| | | ConvertUtil.copyProperties(noticeForm, notice, "id"); |
| | | |
| | | return this.noticeRepository.saveAndFlush(notice); |
| | | } |
| | | |
| | | // 공지사항을 id 로 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Notice getNotice(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.NOTICE_NOT_EXIST)); |
| | | } |
| | | |
| | | Notice notice = this.findOne(id); |
| | | |
| | | if (notice == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.NOTICE_NOT_EXIST)); |
| | | } |
| | | |
| | | return notice; |
| | | } |
| | | |
| | | // 공지사항 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailNotice(Map<String, Object> resJsonData, NoticeCondition noticeCondition) { |
| | | NoticeVo noticeVo = new NoticeVo(); |
| | | |
| | | if (noticeCondition.getId() != null) { |
| | | Notice notice = this.getNotice(noticeCondition.getId()); |
| | | noticeVo = ConvertUtil.copyProperties(notice, NoticeVo.class); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, noticeVo); |
| | | } |
| | | |
| | | // 메세지 보내기 |
| | | @Override |
| | | @Transactional |
| | | public void sendNotice(NoticeForm noticeForm) { |
| | | for (Long userId : noticeForm.getUserIds()) { |
| | | User user = this.userService.getUser(userId); |
| | | |
| | | Map<String, Object> message = new HashMap<>(); |
| | | message.put("url", "/notification/message"); |
| | | message.put("message", noticeForm.getDescription()); |
| | | message.put("account", user.getAccount()); |
| | | this.kafkaSender.send("common-topic", message); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.PaymentHistory; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.PaymentHistoryRepository; |
| | | import kr.wisestone.owl.service.PaymentHistoryService; |
| | | import kr.wisestone.owl.web.form.PaymentForm; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class PaymentHistoryServiceImpl extends AbstractServiceImpl<PaymentHistory, Long, JpaRepository<PaymentHistory, Long>> implements PaymentHistoryService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(PaymentHistoryServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private PaymentHistoryRepository paymentHistoryRepository; |
| | | |
| | | @Override |
| | | protected JpaRepository<PaymentHistory, Long> getRepository() { |
| | | return this.paymentHistoryRepository; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public PaymentHistory addPaymentHistory(PaymentServiceImpl.RestClientResultObject resultObject, PaymentForm paymentForm, Workspace workspace) { |
| | | PaymentHistory paymentHistory = new PaymentHistory(); |
| | | paymentHistory.bindPaymentResult(resultObject); |
| | | paymentHistory.setPrice(paymentForm.getPaymentAmount()); |
| | | paymentHistory.setBuyUser(paymentForm.getBuyUser()); |
| | | paymentHistory.setType(paymentForm.getType()); |
| | | paymentHistory.setCustomerUid(paymentForm.getCustomerUid()); |
| | | paymentHistory.setMerchantUid(paymentForm.getMerchantUid()); |
| | | paymentHistory.setWorkspace(workspace); |
| | | |
| | | return this.paymentHistoryRepository.saveAndFlush(paymentHistory); |
| | | } |
| | | |
| | | // 결제 시 오류가 발생했을 때 취소 정보를 저장한다. |
| | | @Override |
| | | @Transactional |
| | | public PaymentHistory cancelPaymentHistory(PaymentForm paymentForm, Workspace workspace, String reason) { |
| | | PaymentHistory paymentHistory = new PaymentHistory(); |
| | | paymentHistory.setPrice(paymentForm.getPaymentAmount()); |
| | | paymentHistory.setBuyUser(paymentForm.getBuyUser()); |
| | | paymentHistory.setType(paymentForm.getType()); |
| | | paymentHistory.setCustomerUid(paymentForm.getCustomerUid()); |
| | | paymentHistory.setMerchantUid(paymentForm.getMerchantUid()); |
| | | paymentHistory.setWorkspace(workspace); |
| | | paymentHistory.setPaymentResult(PaymentHistory.PAYMENT_RESULT_FAILED); |
| | | paymentHistory.setPaymentResponse(reason); |
| | | |
| | | return this.paymentHistoryRepository.saveAndFlush(paymentHistory); |
| | | } |
| | | |
| | | // 해당 업무 공간에서 마지막으로 결제한 정보를 가져온다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public PaymentHistory findByWorkspaceLastPaymentHistory(Workspace workspace) { |
| | | List<PaymentHistory> paymentHistoryList = this.paymentHistoryRepository.findByWorkspaceId(workspace.getId()); |
| | | |
| | | if (paymentHistoryList.size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_NOT_EXIST)); |
| | | } |
| | | |
| | | return paymentHistoryList.get(paymentHistoryList.size() - 1); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.EmailType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.PaymentRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.DateUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.PaymentHistoryVo; |
| | | import kr.wisestone.owl.vo.PaymentVo; |
| | | import kr.wisestone.owl.vo.UserVo; |
| | | import kr.wisestone.owl.web.form.PaymentForm; |
| | | import org.apache.commons.text.StringEscapeUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.http.HttpEntity; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.http.converter.StringHttpMessageConverter; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.LinkedMultiValueMap; |
| | | import org.springframework.util.MultiValueMap; |
| | | import org.springframework.web.client.HttpClientErrorException; |
| | | import org.springframework.web.client.RestTemplate; |
| | | import org.springframework.web.util.UriComponentsBuilder; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.net.URI; |
| | | import java.net.URLDecoder; |
| | | import java.nio.charset.Charset; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class PaymentServiceImpl extends AbstractServiceImpl<Payment, Long, JpaRepository<Payment, Long>> implements PaymentService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(PaymentServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private PaymentRepository paymentRepository; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private UserWorkspaceService userWorkspaceService; |
| | | |
| | | @Autowired |
| | | private ReservationDisableUserService reservationDisableUserService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private SystemEmailService systemEmailService; |
| | | |
| | | @Autowired |
| | | private PaymentHistoryService paymentHistoryService; |
| | | |
| | | @Value("${saas.usdkrw}") |
| | | private Integer usdKrw; |
| | | |
| | | @Value("${payment.cancel.manager.email}") |
| | | private String paymentCancelManagerEmail; |
| | | |
| | | private static final String IAMPORT_SERVER_URL = "https://api.iamport.kr"; |
| | | private static final String ACCESS_TOKEN_REQUEST_URL = "/users/getToken"; |
| | | private static final String IMP_KEY = "4101736461182334"; |
| | | private static final String IMP_SECRET = "HjTiwAyYJD8r0NRDY0wcmQG989bsOTGvczOJamIT0Rl0FdEDdaQz1wJ9GUCuNj00TOK3btWclic0vREI"; |
| | | private static final String SUBSCRIBE_PAYMENTS_ONETIME = "/subscribe/payments/onetime"; // 최초 결제할때 |
| | | private static final String SUBSCRIBE_PAYMENTS_AGAIN = "/subscribe/payments/again"; // 정기 결제할때 |
| | | private static final String PAYMENTS_CANCEL_URL = "/payments/cancel"; // 취소할때 |
| | | private static final int DEFAULT_BILLING_AMOUNT = 9; |
| | | private static final int BILLING_AMOUNT = 6; |
| | | |
| | | @Override |
| | | protected JpaRepository<Payment, Long> getRepository() { |
| | | return this.paymentRepository; |
| | | } |
| | | |
| | | // 즉시 결제 |
| | | @Override |
| | | @Transactional |
| | | public void immediateAddUser(PaymentForm paymentForm) { |
| | | Workspace workspace = this.workspaceService.findOne(paymentForm.getWorkspaceId()); |
| | | // 서버에서 결재 금액을 다시 계산한다. |
| | | int definiteAmount = this.calculateDailyAmount(paymentForm.getBuyUser(), workspace.getExpireDate()); |
| | | paymentForm.setPaymentAmount(definiteAmount); |
| | | |
| | | // 결재 실행 |
| | | RestClientResultObject resultObject = this.executePayment(paymentForm, workspace); |
| | | // 히스토리 생성 |
| | | PaymentHistory paymentHistory = this.paymentHistoryService.addPaymentHistory(resultObject, paymentForm, workspace); |
| | | // 결재 결과 처리 |
| | | this.paymentResultProcess(paymentHistory, workspace, paymentForm, true); |
| | | } |
| | | |
| | | private int calculateDailyAmount(int buyUser, Date expireDate) { |
| | | |
| | | int expireDateTerm = DateUtil.getDateDiff(new Date(), expireDate) + 1; |
| | | |
| | | // 사용자가 1명이 안될 때는 오류 발생 |
| | | if (buyUser < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_BUY_USER_MUST_BE_GREATER_THAN_ZERO)); |
| | | } |
| | | |
| | | if (expireDateTerm > 29) { |
| | | // 기본 사용자(10명)을 초과한 결제를 진행했을 때 결제 금액을 계산한다. |
| | | return this.calculateAmountDefaultUserOver(buyUser); |
| | | } |
| | | else { |
| | | int totalAmount = (BILLING_AMOUNT * this.usdKrw * buyUser); |
| | | int dayAmount = (totalAmount / 30); // 30일 기준으로 가격을 나눈다. |
| | | double sale = buyUser * 0.01; |
| | | double discount = 0; |
| | | |
| | | // 100명 이상 결제시 할인 적용 |
| | | if (buyUser > 99) { |
| | | discount = (totalAmount * (sale / 100)); |
| | | } |
| | | |
| | | return (int) Math.round((dayAmount * expireDateTerm) - discount); |
| | | } |
| | | } |
| | | |
| | | // 기본 사용자(10명)을 초과한 결제를 진행했을 때 결제 금액을 계산한다. |
| | | private int calculateAmountDefaultUserOver(int buyUser) { |
| | | // 100프로 |
| | | int totalAmount = (BILLING_AMOUNT * this.usdKrw * buyUser); |
| | | double sale = buyUser * 0.01; |
| | | double discount = 0; |
| | | |
| | | // 100명 이상 결제시 할인 적용 |
| | | if (buyUser > 99) { |
| | | discount = (totalAmount * (sale / 100)); |
| | | } |
| | | |
| | | return (int) Math.floor((totalAmount - discount)); |
| | | } |
| | | |
| | | // 정기 결제 |
| | | @Override |
| | | @Transactional |
| | | public void paymentOneTime(PaymentForm paymentForm) { |
| | | Workspace workspace = this.workspaceService.getWorkspace(paymentForm.getWorkspaceId()); |
| | | // 결제하려는 사용자가 업무 공간의 관리자인지 확인한다. |
| | | this.checkWorkspaceManager(workspace); |
| | | // 구매 사용자 수 체크 |
| | | this.verifyBuyUser(paymentForm); |
| | | // 결제 유형 체크 |
| | | this.verifyPaymentType(paymentForm.getType()); |
| | | |
| | | // 서버에서 결제 금액을 다시 계산한다. |
| | | int definiteAmount = this.calculateAmount(paymentForm.getBuyUser()); |
| | | paymentForm.setPaymentAmount(definiteAmount); |
| | | // 결제 실행 |
| | | RestClientResultObject resultObject = this.executePayment(paymentForm, workspace); |
| | | // 히스토리 생성 |
| | | PaymentHistory paymentHistory = this.paymentHistoryService.addPaymentHistory(resultObject, paymentForm, workspace); |
| | | // 결제 결과 처리 |
| | | this.paymentResultProcess(paymentHistory, workspace, paymentForm, false); |
| | | |
| | | // 결제 정보를 map 으로 만들어준다. - 이메일 발송에 사용 |
| | | Map<String, Object> paymentMap = this.makePaymentMap(workspace, this.webAppUtil.getLoginUser().getName(), paymentForm.getBuyUser(), definiteAmount, null); |
| | | |
| | | // 결제 성공 메일 발송 |
| | | this.systemEmailService.directEmail(new String[]{this.webAppUtil.getLoginUser().getAccount()}, EmailType.REGULAR_PAYMENT, paymentMap, this.webAppUtil.getLoginUser().getAccount()); |
| | | } |
| | | |
| | | // 결제 정보를 map 으로 만들어준다. - 이메일 발송에 사용 |
| | | private Map<String, Object> makePaymentMap(Workspace workspace, String userName, Integer buyUser, Integer price, String email) { |
| | | Map<String, Object> paymentMap = new HashMap<>(); |
| | | paymentMap.put("userName", userName); |
| | | paymentMap.put("workspaceName", workspace.getName()); |
| | | paymentMap.put("storageSize", workspace.getStorageSize() / 1024 / 1024 / 1024); |
| | | paymentMap.put("buyUser", buyUser); |
| | | paymentMap.put("price", CommonUtil.getDecimalFormat(price)); |
| | | paymentMap.put("registerDate", DateUtil.convertDateToStr(new Date())); |
| | | paymentMap.put("nextPaymentDay", DateUtil.convertDateToYYYYMMDD(DateUtil.addDays(workspace.getExpireDate(), 1))); |
| | | paymentMap.put("startDate", DateUtil.convertDateToYYYYMMDD(workspace.getStartDate())); |
| | | paymentMap.put("expireDate", DateUtil.convertDateToYYYYMMDD(workspace.getExpireDate())); |
| | | paymentMap.put("email", email); |
| | | |
| | | return paymentMap; |
| | | } |
| | | |
| | | // 결제하려는 사용자가 업무 공간의 관리자인지 확인한다. |
| | | private void checkWorkspaceManager(Workspace workspace) { |
| | | UserWorkspace userWorkspace = this.userWorkspaceService.findByUserIdAndWorkspaceId(this.webAppUtil.getLoginId(), workspace.getId()); |
| | | |
| | | if (!userWorkspace.getManagerYn()) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_EXECUTE_ONLY_WORKSPACE_MANAGER)); |
| | | } |
| | | } |
| | | |
| | | // 스케쥴러로 한번 결제한 정보를 토대로 자동 결제를 실행한다. |
| | | @Override |
| | | @Transactional |
| | | public void subscribeImmediate(Workspace workspace) { |
| | | Payment payment = workspace.getPayment(); |
| | | |
| | | if (payment == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_NOT_EXIST)); |
| | | } |
| | | |
| | | User workspaceManager = this.userService.findByWorkspaceIdAndManagerYn(workspace); |
| | | |
| | | if (workspaceManager == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.USER_WORKSPACE_MANAGER_NOT_EXIST)); |
| | | } |
| | | |
| | | PaymentForm paymentForm = ConvertUtil.copyProperties(payment, PaymentForm.class); |
| | | paymentForm.setCustomerUid(workspace.makeCustomerUid(workspaceManager.getAccount())); |
| | | paymentForm.setMerchantUid(workspaceManager.getAccount() + new Date().getTime()); |
| | | paymentForm.setPaymentAmount(payment.getPrice()); // 히스토리 생성할 때 사용 |
| | | |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Authorization", this.getAccessToken()); |
| | | |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8"))); |
| | | |
| | | MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); |
| | | parameters.add("customer_uid", paymentForm.getCustomerUid()); |
| | | parameters.add("merchant_uid", paymentForm.getMerchantUid()); |
| | | parameters.add("amount", paymentForm.getPaymentAmount().toString()); |
| | | |
| | | RestClientResultObject resultObject = this.postRequest(this.makeIamportRequestUrl(SUBSCRIBE_PAYMENTS_AGAIN), new HttpEntity<>(parameters, headers)); |
| | | // 히스토리 생성 |
| | | PaymentHistory paymentHistory = this.paymentHistoryService.addPaymentHistory(resultObject, paymentForm, workspace); |
| | | // 결제 결과 처리 |
| | | this.paymentResultProcess(paymentHistory, workspace, paymentForm, false); |
| | | // 비활성화 사용자 처리 |
| | | this.checkPaymentByUserCount(paymentHistory, payment, paymentForm, workspace); |
| | | |
| | | List<UserWorkspace> userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), true); |
| | | // 업무 공간 담당자 이름 |
| | | String workspaceManagerName = ""; |
| | | |
| | | if (userWorkspaces.size() > 0) { |
| | | workspaceManagerName = userWorkspaces.get(0).getUser().getName(); |
| | | } |
| | | |
| | | // 결제 정보를 map 으로 만들어준다. - 이메일 발송에 사용 |
| | | Map<String, Object> paymentMap = this.makePaymentMap(workspace, workspaceManagerName, payment.getBuyUser(), payment.getPrice(), null); |
| | | |
| | | // 결제 성공 메일 발송 |
| | | this.systemEmailService.directEmail(new String[]{workspaceManager.getAccount()}, EmailType.REGULAR_PAYMENT, paymentMap, null); |
| | | } |
| | | |
| | | // 결제된 사용자 수를 체크한다. |
| | | private void checkPaymentByUserCount(PaymentHistory paymentHistory, Payment payment, PaymentForm paymentForm, Workspace workspace) { |
| | | try { |
| | | // 결제가 성공했을 때 참여 사용자와 결제된 사용자 수를 비교한다. |
| | | if (paymentHistory.getPaymentResult().equals(PaymentHistory.PAYMENT_RESULT_SUCCESS)) { |
| | | Integer activeUserCount = this.userWorkspaceService.countByWorkspaceIdAndUseYn(workspace.getId(), true); |
| | | |
| | | // 결제한 사용자보다 참여중인 사용자가 많을 경우 |
| | | if (workspace.getMaxUser() < activeUserCount) { |
| | | this.executeWorkspaceStandbyUser(workspace, payment, activeUserCount); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | this.cancelPayment(paymentForm.getMerchantUid(), ""); |
| | | this.paymentHistoryService.cancelPaymentHistory(paymentForm, workspace, "결제 완료후 비활성화로 예정된 사용자 처리 과정에서 오류가 발생하였습니다."); |
| | | } |
| | | } |
| | | |
| | | // 업무 공간에 참여하는 사용자 참여 대기 상태로 변경하기 - 결제 인원 수를 제외한 인원들 |
| | | private void executeWorkspaceStandbyUser(Workspace workspace, Payment payment, Integer activeUserCount) { |
| | | int disableUserCount = activeUserCount - workspace.getMaxUser(); |
| | | // 참여 대기로 예약된 사용자부터 참여 대기로 상태를 변경 |
| | | ReservationDisableUser reservationDisableUser = payment.getReservationDisableUser(); |
| | | |
| | | if (reservationDisableUser != null) { |
| | | String[] userIds = reservationDisableUser.getUserIds().split(","); |
| | | |
| | | for (String userId : userIds) { |
| | | if (!StringUtils.isEmpty(userId)) { |
| | | if (disableUserCount < 1) { |
| | | break; |
| | | } |
| | | |
| | | User user = this.userService.getUser(Long.valueOf(userId)); |
| | | // 해당 업무 공간에서 사용자를 비활성화한다. |
| | | this.userWorkspaceService.disabledUserWorkspace(user, workspace); |
| | | // 사용자를 해당 업무 공간에서 참여 대기 상태로 변경했으면 카운터를 내린다. |
| | | disableUserCount--; |
| | | } |
| | | } |
| | | |
| | | payment.setReservationDisableUser(null); |
| | | this.paymentRepository.saveAndFlush(payment); |
| | | } |
| | | |
| | | // 해당 업무 공간에 참여하는 사용자 중 번호가 높은 순서대로 참여 대기 상태로 변경한다. |
| | | List<UserWorkspace> userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndUseYn(workspace.getId(), true); |
| | | |
| | | for (UserWorkspace userWorkspace : userWorkspaces) { |
| | | // 관리자는 항상 참여 상태여야 한다. |
| | | if (userWorkspace.getManagerYn()) { |
| | | continue; |
| | | } |
| | | |
| | | if (disableUserCount < 1) { |
| | | break; |
| | | } |
| | | |
| | | // 해당 업무 공간에서 사용자를 비활성화한다. |
| | | this.userWorkspaceService.disabledUserWorkspace(userWorkspace.getUser(), workspace); |
| | | // 사용자를 해당 업무 공간에서 참여 대기 상태로 변경했으면 카운터를 내린다. |
| | | disableUserCount--; |
| | | } |
| | | } |
| | | |
| | | // 서버에서 결제 금액을 다시 계산한다. |
| | | private int calculateAmount(int buyUser) { |
| | | // 사용자가 1명이 안될 때는 오류 발생 |
| | | if (buyUser < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_BUY_USER_MUST_BE_GREATER_THAN_ZERO)); |
| | | } |
| | | |
| | | if (buyUser < 11) { |
| | | return (DEFAULT_BILLING_AMOUNT * this.usdKrw); |
| | | } |
| | | else { |
| | | // 기본 사용자(10명)을 초과한 결제를 진행했을 때 결제 금액을 계산한다. |
| | | return this.calculateAmountDefaultUserOver(buyUser); |
| | | } |
| | | } |
| | | |
| | | // 결제를 실행한다. |
| | | private RestClientResultObject executePayment(PaymentForm paymentForm, Workspace workspace) { |
| | | UserVo workspaceManager = this.webAppUtil.getLoginUser(); |
| | | paymentForm.setCustomerUid(workspace.makeCustomerUid(workspaceManager.getAccount())); |
| | | paymentForm.setMerchantUid(workspaceManager.getAccount() + new Date().getTime()); |
| | | // HttpHeader 를 생성한다. |
| | | HttpHeaders headers = this.makeHttpHeader(); |
| | | |
| | | MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); |
| | | parameters.add("merchant_uid", paymentForm.getMerchantUid()); |
| | | parameters.add("amount", paymentForm.getPaymentAmount().toString()); |
| | | parameters.add("card_number", CommonUtil.decryptAES128(paymentForm.getCardNumber1()) + "-" + CommonUtil.decryptAES128(paymentForm.getCardNumber2()) |
| | | + "-" + CommonUtil.decryptAES128(paymentForm.getCardNumber3()) + "-" + CommonUtil.decryptAES128(paymentForm.getCardNumber4())); |
| | | parameters.add("expiry", CommonUtil.decryptAES128(paymentForm.getExpireYear()) + "-" + CommonUtil.decryptAES128(paymentForm.getExpireMonth())); |
| | | parameters.add("birth", CommonUtil.decryptAES128(paymentForm.getBirth())); |
| | | parameters.add("pwd_2digit", CommonUtil.decryptAES128(paymentForm.getCardPwd())); |
| | | parameters.add("customer_uid", paymentForm.getCustomerUid()); |
| | | parameters.add("buyer_name", workspaceManager.getName()); |
| | | parameters.add("buyer_email", workspaceManager.getAccount()); |
| | | |
| | | return this.postRequest(this.makeIamportRequestUrl(SUBSCRIBE_PAYMENTS_ONETIME), new HttpEntity<>(parameters, headers)); |
| | | } |
| | | |
| | | // 결제 결과를 처리한다. |
| | | private PaymentHistoryVo paymentResultProcess(PaymentHistory paymentHistory, Workspace workspace, PaymentForm paymentForm, Boolean immediate) { |
| | | if (paymentHistory.getPaymentResult().equals(PaymentHistory.PAYMENT_RESULT_SUCCESS)) { |
| | | try { |
| | | // 추가 결제 |
| | | if (immediate) { |
| | | Payment payment = workspace.getPayment(); |
| | | // 인원 추가 |
| | | payment.setBuyUser(payment.getBuyUser() + paymentForm.getBuyUser()); |
| | | // 추가 결제로 인한 사용금액 변경 |
| | | payment.setPrice(this.calculateAmountDefaultUserOver(payment.getBuyUser())); |
| | | this.paymentRepository.saveAndFlush(payment); |
| | | // 추가 결제 완료 후 최대 사용자 수, 저장 공간을 업데이트한다. |
| | | this.workspaceService.updateWorkspaceByImmediatePayment(workspace, payment.getBuyUser()); |
| | | } |
| | | else { |
| | | // 정기 결제로 결제를 진행한 경우 |
| | | Payment payment = this.executePaymentOneTime(workspace, paymentForm); |
| | | |
| | | if (payment != null) { |
| | | // 비활성화 사용자 처리 |
| | | this.checkPaymentByUserCount(paymentHistory, payment, paymentForm, workspace); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | this.cancelPayment(paymentForm.getMerchantUid(), ""); |
| | | PaymentHistory cancelPaymentHistory = this.paymentHistoryService.cancelPaymentHistory(paymentForm, workspace, "결제 과정에서 오류가 발생하였습니다. 다시 시도해 주세요."); |
| | | return ConvertUtil.copyProperties(cancelPaymentHistory, PaymentHistoryVo.class); |
| | | } |
| | | } |
| | | else { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(paymentHistory.getPaymentResponse())); |
| | | } |
| | | |
| | | return ConvertUtil.copyProperties(paymentHistory, PaymentHistoryVo.class); |
| | | } |
| | | |
| | | // 정기 결제로 결제를 진행한 경우 |
| | | private Payment executePaymentOneTime(Workspace workspace, PaymentForm paymentForm) { |
| | | // 다음 결제일 지정 및 업무 공간에 결제한 신규 데이터 적용 |
| | | this.workspaceService.updateWorkspace(workspace, paymentForm); |
| | | |
| | | if (workspace.getPayment() == null) { |
| | | // 결제가 완료되고 결제 정보가 업무 공간에 업데이트가 되면 정기 결제를 위해 결제 정보를 생성한다. |
| | | Payment payment = ConvertUtil.copyProperties(paymentForm, Payment.class); |
| | | payment.setPrice(paymentForm.getPaymentAmount()); |
| | | payment.setWorkspace(workspace); |
| | | return this.paymentRepository.saveAndFlush(payment); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | // 결제 진행중 발생한 오류로 인한 결제 취소 요청 |
| | | private String cancelPayment(String merchantUid, String reason) { |
| | | // HttpHeader 를 생성한다. |
| | | HttpHeaders headers = this.makeHttpHeader(); |
| | | // RestTemplate 를 생성한다. |
| | | RestTemplate restTemplate = this.makeRestTemplate(); |
| | | |
| | | MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); |
| | | parameters.add("merchant_uid", merchantUid); |
| | | parameters.add("reason", reason); |
| | | |
| | | URI targetUrl = UriComponentsBuilder.fromUriString(IAMPORT_SERVER_URL) |
| | | .path(PAYMENTS_CANCEL_URL) |
| | | .build() |
| | | .toUri(); |
| | | |
| | | String url = null; |
| | | |
| | | try { |
| | | url = URLDecoder.decode(targetUrl.toString(), "UTF-8"); |
| | | } catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | ResponseEntity<String> result = restTemplate.postForEntity(url, new HttpEntity<>(parameters, headers), String.class); |
| | | Map<String, Object> resultMap = ConvertUtil.convertJsonToMap(result.getBody()); |
| | | return StringEscapeUtils.unescapeJava(MapUtil.getString(resultMap, "response")); |
| | | } |
| | | |
| | | // HttpHeader 를 생성한다. |
| | | private HttpHeaders makeHttpHeader() { |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Authorization", this.getAccessToken()); |
| | | |
| | | return headers; |
| | | } |
| | | |
| | | // RestTemplate 를 생성한다. |
| | | private RestTemplate makeRestTemplate() { |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | restTemplate.getMessageConverters() |
| | | .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8"))); |
| | | |
| | | return restTemplate; |
| | | } |
| | | |
| | | // 정기 결제 취소하기 |
| | | @Override |
| | | @Transactional |
| | | public void cancelNextPayment(PaymentForm paymentForm) { |
| | | Workspace workspace = this.workspaceService.getWorkspace(paymentForm.getWorkspaceId()); |
| | | // 결제 취소하려는 사용자가 업무 공간의 관리자인지 확인한다. |
| | | this.checkWorkspaceManager(workspace); |
| | | |
| | | Payment payment = workspace.getPayment(); |
| | | |
| | | if (payment == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_NOT_EXIST)); |
| | | } |
| | | // 업무 공간 정기 결제 취소 - 정기 결제 정보 삭제 |
| | | this.workspaceService.cancelWorkspacePayment(workspace); |
| | | |
| | | // 결제 정보를 map 으로 만들어준다. - 이메일 발송에 사용 |
| | | Map<String, Object> paymentMap = this.makePaymentMap(workspace, this.webAppUtil.getLoginUser().getName(), 0, 0, CommonUtil.decryptAES128(this.webAppUtil.getLoginUser().getAccount())); |
| | | paymentMap.put("maxUser", workspace.getMaxUser()); |
| | | |
| | | try { |
| | | // 오늘 결제한 업무 공간을 사용자가 취소했는지 확인한다. |
| | | PaymentHistory paymentHistory = this.paymentHistoryService.findByWorkspaceLastPaymentHistory(workspace); |
| | | |
| | | // 당일 결제 취소일 경우 |
| | | if (paymentHistory.getRegisterDate().compareTo(new Date()) == 0) { |
| | | paymentMap.put("refundPrice", CommonUtil.getDecimalFormat(paymentHistory.getPrice())); // 환불 금액 |
| | | // 회계 담당자 이메일 주소 암호화 |
| | | String encryptAccountingManager = CommonUtil.encryptAES128(this.paymentCancelManagerEmail); |
| | | // 회계 담당자에게 결제 취소 알림 메일 |
| | | this.systemEmailService.directEmail(new String[]{encryptAccountingManager}, EmailType.REGULAR_PAYMENT_CANCEL_BY_ACCOUNTING_MANAGER, paymentMap, encryptAccountingManager); |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | log.debug("환불 알림 메일 오류 발생" + e.getMessage()); |
| | | } |
| | | |
| | | // 정기 결제 취소 알림 메일 |
| | | this.systemEmailService.directEmail(new String[]{this.webAppUtil.getLoginUser().getAccount()}, EmailType.REGULAR_PAYMENT_CANCEL, paymentMap, this.webAppUtil.getLoginUser().getAccount()); |
| | | } |
| | | |
| | | @Override |
| | | public String getAccessToken() { |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | restTemplate.getMessageConverters() |
| | | .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8"))); |
| | | |
| | | MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); |
| | | parameters.add("imp_key", IMP_KEY); |
| | | parameters.add("imp_secret", IMP_SECRET); |
| | | |
| | | URI targetUrl = UriComponentsBuilder.fromUriString(IAMPORT_SERVER_URL) |
| | | .path(ACCESS_TOKEN_REQUEST_URL) |
| | | .build() |
| | | .toUri(); |
| | | |
| | | String url = ""; |
| | | |
| | | try { |
| | | url = URLDecoder.decode(targetUrl.toString(), "UTF-8"); |
| | | } catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | String result = restTemplate.postForObject(url, parameters, String.class); |
| | | Map<String, Object> resultMap = ConvertUtil.convertJsonToMap(result); |
| | | Map<String, Object> tokenMap = (Map<String, Object>) resultMap.get("response"); |
| | | return MapUtil.getString(tokenMap, "access_token"); |
| | | } |
| | | |
| | | // 결제 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailPayment(Map<String, Object> resJsonData, PaymentForm paymentForm) { |
| | | Workspace workspace = this.workspaceService.findOne(paymentForm.getWorkspaceId()); |
| | | Payment payment = workspace.getPayment(); |
| | | |
| | | if (payment != null) { |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, ConvertUtil.copyProperties(payment, PaymentVo.class)); |
| | | } |
| | | } |
| | | |
| | | // 결제 정보를 수정한다. |
| | | @Override |
| | | @Transactional |
| | | public PaymentVo modifyPayment(PaymentForm paymentForm) { |
| | | Workspace workspace = this.workspaceService.findOne(paymentForm.getWorkspaceId()); |
| | | // 결제하려는 사용자가 업무 공간의 관리자인지 확인한다. |
| | | this.checkWorkspaceManager(workspace); |
| | | |
| | | Payment payment = workspace.getPayment(); |
| | | |
| | | Map<String, Object> paymentMap = new HashMap<>(); |
| | | paymentMap.put("beforeMaxUser", payment.getBuyUser()); // 이전 최대 사용자 수 |
| | | paymentMap.put("beforePrice", CommonUtil.getDecimalFormat(payment.getPrice())); // 이전 가격 |
| | | |
| | | // 결제 사용자 수 체크 |
| | | this.verifyBuyUser(paymentForm); |
| | | |
| | | // 결제 유형 체크 |
| | | this.verifyPaymentType(paymentForm.getType()); |
| | | payment.setBuyUser(paymentForm.getBuyUser()); |
| | | payment.setType(paymentForm.getType()); |
| | | |
| | | // 서버에서 결제 금액을 다시 계산한다. |
| | | int definiteAmount = this.calculateAmount(paymentForm.getBuyUser()); |
| | | payment.setPrice(definiteAmount); |
| | | |
| | | if (payment.getReservationDisableUser() != null) { |
| | | payment.setReservationDisableUser(null); |
| | | } |
| | | |
| | | this.paymentRepository.saveAndFlush(payment); |
| | | this.reservationDisableUserService.add(paymentForm, payment); |
| | | |
| | | paymentMap.put("userName", this.webAppUtil.getLoginUser().getName()); |
| | | paymentMap.put("workspaceName", workspace.getName()); |
| | | paymentMap.put("maxUser", paymentForm.getBuyUser()); |
| | | paymentMap.put("price", CommonUtil.getDecimalFormat(definiteAmount)); |
| | | paymentMap.put("nextPaymentDay", DateUtil.convertDateToYYYYMMDD(DateUtil.addDays(workspace.getExpireDate(), 1))); |
| | | |
| | | // 정기 결제 변경 알림 메일 |
| | | this.systemEmailService.directEmail(new String[]{this.webAppUtil.getLoginUser().getAccount()}, EmailType.REGULAR_PAYMENT_MODIFY, paymentMap, this.webAppUtil.getLoginUser().getAccount()); |
| | | |
| | | return ConvertUtil.copyProperties(payment, PaymentVo.class); |
| | | } |
| | | |
| | | // 결제 사용자 수 체크 |
| | | private void verifyBuyUser(PaymentForm paymentForm) { |
| | | if (paymentForm.getBuyUser() == null || paymentForm.getBuyUser() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_BUY_USER_MUST_BE_GREATER_THAN_ZERO)); |
| | | } |
| | | |
| | | // 1명으로 구입해도 10인까지 사용 가능하도록 변경 |
| | | if (paymentForm.getBuyUser() < 10) { |
| | | paymentForm.setBuyUser(10); |
| | | } |
| | | } |
| | | |
| | | // 결제 유형 체크 |
| | | private void verifyPaymentType(String type) { |
| | | if (StringUtils.isEmpty(type)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_NO_TYPE)); |
| | | } |
| | | } |
| | | |
| | | // 결제 아이디로 결제를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Payment getPayment(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_NOT_EXIST)); |
| | | } |
| | | |
| | | Payment payment = this.findOne(id); |
| | | |
| | | if (payment == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PAYMENT_NOT_EXIST)); |
| | | } |
| | | |
| | | return payment; |
| | | } |
| | | |
| | | // 결제 금액에 환율 정보를 업데이트한다. |
| | | @Override |
| | | @Transactional |
| | | public void updateExchangeRatePayment() { |
| | | List<Payment> payments = this.paymentRepository.findAll(); |
| | | |
| | | for (Payment payment : payments) { |
| | | // 서버에서 결제 금액을 다시 계산한다. |
| | | int definiteAmount = this.calculateAmount(payment.getBuyUser()); |
| | | payment.setPrice(definiteAmount); |
| | | } |
| | | |
| | | this.paymentRepository.saveAll(payments); |
| | | } |
| | | |
| | | private URI makeIamportRequestUrl(String requestPath) { |
| | | return UriComponentsBuilder.fromUriString(IAMPORT_SERVER_URL) |
| | | .path(requestPath) |
| | | .build() |
| | | .toUri(); |
| | | } |
| | | |
| | | private RestClientResultObject postRequest(URI targetUrl, HttpEntity<MultiValueMap<String, String>> request) { |
| | | RestClientResultObject restResult = new RestClientResultObject(); |
| | | RestTemplate restTemplate = new RestTemplate(); |
| | | restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8"))); |
| | | |
| | | try { |
| | | String url = URLDecoder.decode(targetUrl.toString(), "UTF-8"); |
| | | ResponseEntity<String> result = restTemplate.postForEntity(url, request, String.class); |
| | | Map<String, Object> resultMap = ConvertUtil.convertJsonToMap(result.getBody()); |
| | | |
| | | restResult.setHttpStatus(result.getStatusCode()); |
| | | restResult.setCode(MapUtil.getString(resultMap, "code")); |
| | | |
| | | if (resultMap.containsKey("message")) { |
| | | restResult.setMessage(StringEscapeUtils.unescapeJava(MapUtil.getString(resultMap, "message"))); |
| | | } |
| | | |
| | | if (resultMap.containsKey("response")) { |
| | | Map<String, Object> response = (Map<String, Object>) resultMap.get("response"); |
| | | restResult.setResponse(response); |
| | | |
| | | String responseStatus = MapUtil.getString(response, "status"); |
| | | String failReason = MapUtil.getString(response, "fail_reason"); |
| | | |
| | | restResult.setIamportStatus(responseStatus); |
| | | |
| | | Boolean isNotPaidResult = !"paid".equals(responseStatus); |
| | | |
| | | if (isNotPaidResult) { |
| | | restResult.setIamportFailReason(failReason); |
| | | } |
| | | } |
| | | |
| | | } catch (HttpClientErrorException e) { |
| | | |
| | | restResult.setMessage(e.getMessage()); |
| | | restResult.setCode(e.getStatusCode().toString()); |
| | | restResult.setHttpStatus(e.getStatusCode()); |
| | | |
| | | } catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return restResult; |
| | | } |
| | | |
| | | public static class RestClientResultObject { |
| | | private static final String CODE_RESULT_SUCCESS = "0"; |
| | | private static final String CODE_RESULT_FAILED = "-1"; |
| | | private static final String IAMPORT_STATUS_PAID = "paid"; |
| | | |
| | | |
| | | private HttpStatus httpStatus; |
| | | private String code; |
| | | private String message; |
| | | private Map<String, Object> response; |
| | | private String iamportStatus; |
| | | private String iamportFailReason; |
| | | |
| | | public Boolean isValidResult() { |
| | | if (isHttpRequestFailed() || isIamportResultFailed() || isIamportPaymentFailed()) { |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | public Boolean isHttpRequestFailed() { |
| | | return !HttpStatus.OK.equals(this.getHttpStatus()); |
| | | } |
| | | |
| | | public Boolean isIamportResultFailed() { |
| | | return CODE_RESULT_FAILED.equals(this.getCode()); |
| | | } |
| | | |
| | | public Boolean isIamportPaymentFailed() { |
| | | return !IAMPORT_STATUS_PAID.equals(this.getIamportStatus()); |
| | | } |
| | | |
| | | public HttpStatus getHttpStatus() { |
| | | return httpStatus; |
| | | } |
| | | |
| | | public void setHttpStatus(HttpStatus httpStatus) { |
| | | this.httpStatus = httpStatus; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public void setMessage(String message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | public Map<String, Object> getResponse() { |
| | | return response; |
| | | } |
| | | |
| | | public void setResponse(Map<String, Object> response) { |
| | | this.response = response; |
| | | } |
| | | |
| | | public String getIamportStatus() { |
| | | return iamportStatus; |
| | | } |
| | | |
| | | public void setIamportStatus(String iamportStatus) { |
| | | this.iamportStatus = iamportStatus; |
| | | } |
| | | |
| | | public String getIamportFailReason() { |
| | | return iamportFailReason; |
| | | } |
| | | |
| | | public void setIamportFailReason(String iamportFailReason) { |
| | | this.iamportFailReason = iamportFailReason; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.base.Predicate; |
| | | import com.google.common.collect.Iterables; |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.domain.Permission; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.repository.PermissionRepository; |
| | | import kr.wisestone.owl.service.PermissionService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.PermissionVo; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class PermissionServiceImpl extends AbstractServiceImpl<Permission, Long, JpaRepository<Permission, Long>> implements PermissionService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(PermissionServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private PermissionRepository permissionRepository; |
| | | |
| | | @Override |
| | | protected JpaRepository<Permission, Long> getRepository() { |
| | | return this.permissionRepository; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<PermissionVo> findByUserId() { |
| | | |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | |
| | | List<PermissionVo> allPermission = ConvertUtil.convertObjectsToClasses(this.permissionRepository.findAll(), PermissionVo.class); |
| | | List<PermissionVo> userPermissions = Lists.newArrayList(); |
| | | |
| | | if (user != null) { |
| | | userPermissions.addAll(ConvertUtil.convertObjectsToClasses(this.permissionRepository.findByUserId(user.getId()), PermissionVo.class)); |
| | | } |
| | | |
| | | this.setPermissionActiveYn(allPermission, userPermissions); |
| | | |
| | | return allPermission; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Permission> findByRoleType(String roleType) { |
| | | return this.permissionRepository.findByRoleType(roleType); |
| | | } |
| | | |
| | | private void setPermissionActiveYn(List<PermissionVo> allPermissionVos, List<PermissionVo> userPermissionVos) { |
| | | for (PermissionVo permissionVo : allPermissionVos) { |
| | | |
| | | final Long permissionId = permissionVo.getId(); |
| | | |
| | | PermissionVo userPermission = Iterables.find(userPermissionVos, new Predicate<PermissionVo>() { |
| | | @Override |
| | | public boolean apply(PermissionVo input) { |
| | | return input.getId().equals(permissionId); |
| | | } |
| | | }, null); |
| | | |
| | | if (userPermission != null) { |
| | | permissionVo.setActiveYn(Boolean.TRUE); |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.Priority; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.PriorityRepository; |
| | | import kr.wisestone.owl.service.PriorityService; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.PriorityVo; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class PriorityServiceImpl extends AbstractServiceImpl<Priority, Long, JpaRepository<Priority, Long>> implements PriorityService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(PriorityServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private PriorityRepository priorityRepository; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Override |
| | | protected JpaRepository<Priority, Long> getRepository() { |
| | | return this.priorityRepository; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Priority> findByWorkspaceIdOrderByPosition() { |
| | | Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | return this.priorityRepository.findByWorkspaceIdOrderByPosition(workspace.getId()); |
| | | } |
| | | |
| | | // 우선순위 아이디로 우선순위를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Priority getPriority(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PRIORITY_NOT_EXIST)); |
| | | } |
| | | |
| | | Priority priority = this.findOne(id); |
| | | |
| | | if (priority == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PRIORITY_NOT_EXIST)); |
| | | } |
| | | |
| | | return priority; |
| | | } |
| | | |
| | | // 우선순위 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<PriorityVo> findPriority(Map<String, Object> resJsonData) { |
| | | List<PriorityVo> priorityVos = ConvertUtil.convertObjectsToClasses(this.findByWorkspaceIdOrderByPosition(), PriorityVo.class); |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, priorityVos); |
| | | |
| | | return priorityVos; |
| | | } |
| | | |
| | | |
| | | // 기본적으로 제공되는 우선순위 목록 |
| | | @Override |
| | | @Transactional |
| | | public void addDefaultPriority(Workspace workspace) { |
| | | List<Priority> priorities = Lists.newArrayList(); |
| | | priorities.add(new Priority(this.messageAccessor.message("common.urgent"), 1, "#ed5565", workspace)); |
| | | priorities.add(new Priority(this.messageAccessor.message("common.high"), 2, "#f8ac59", workspace)); |
| | | priorities.add(new Priority(this.messageAccessor.message("common.medium"), 3, "#1c84c6", workspace)); |
| | | priorities.add(new Priority(this.messageAccessor.message("common.low"), 4, "#23c6c8", workspace)); |
| | | |
| | | this.priorityRepository.saveAll(priorities); |
| | | } |
| | | |
| | | // 업무공간에 있는 우선 순위 목록을 가져온다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Priority> findByWorkspaceId() { |
| | | return this.priorityRepository.findByWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import kr.wisestone.owl.domain.Priority; |
| | | import kr.wisestone.owl.domain.Project; |
| | | import kr.wisestone.owl.domain.ProjectClosure; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.repository.ProjectClosureRepository; |
| | | import kr.wisestone.owl.service.ProjectClosureService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | @Service |
| | | public class ProjectClosureServiceImpl extends AbstractServiceImpl<ProjectClosure, Long, JpaRepository<ProjectClosure, Long>> implements ProjectClosureService { |
| | | private static final Logger log = LoggerFactory.getLogger(ProjectClosureServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private ProjectClosureRepository projectClosureRepository; |
| | | |
| | | @Override |
| | | protected JpaRepository<ProjectClosure, Long> getRepository() { |
| | | return this.projectClosureRepository; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.domain.Permission; |
| | | import kr.wisestone.owl.domain.ProjectRole; |
| | | import kr.wisestone.owl.domain.ProjectRolePermission; |
| | | import kr.wisestone.owl.repository.ProjectRolePermissionRepository; |
| | | import kr.wisestone.owl.service.PermissionService; |
| | | import kr.wisestone.owl.service.ProjectRolePermissionService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class ProjectRolePermissionServiceImpl extends AbstractServiceImpl<ProjectRolePermission, Long, JpaRepository<ProjectRolePermission, Long>> implements ProjectRolePermissionService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ProjectRolePermissionServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private ProjectRolePermissionRepository projectRolePermissionRepository; |
| | | |
| | | @Autowired |
| | | private PermissionService permissionService; |
| | | |
| | | @Override |
| | | protected JpaRepository<ProjectRolePermission, Long> getRepository() { |
| | | return this.projectRolePermissionRepository; |
| | | } |
| | | |
| | | // 해당 프로젝트 역할과 권한을 연결시킨다. |
| | | @Override |
| | | @Transactional |
| | | public void addDefaultProjectRoleAssociatedPermissions(ProjectRole projectRole, String roleType) { |
| | | List<Permission> permissions = this.permissionService.findByRoleType(roleType); |
| | | List<ProjectRolePermission> projectRolePermissions = Lists.newArrayList(); |
| | | |
| | | permissions.parallelStream().forEach(permission -> { |
| | | ProjectRolePermission projectRolePermission = new ProjectRolePermission(projectRole, permission); |
| | | projectRolePermissions.add(projectRolePermission); |
| | | }); |
| | | |
| | | this.projectRolePermissionRepository.saveAll(projectRolePermissions); |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.ProjectRoleRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class ProjectRoleServiceImpl extends AbstractServiceImpl<ProjectRole, Long, JpaRepository<ProjectRole, Long>> implements ProjectRoleService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ProjectRoleServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private ProjectRoleRepository projectRoleRepository; |
| | | |
| | | @Autowired |
| | | private ProjectRoleUserService projectRoleUserService; |
| | | |
| | | @Autowired |
| | | private ProjectRolePermissionService projectRolePermissionService; |
| | | |
| | | @Override |
| | | protected JpaRepository<ProjectRole, Long> getRepository() { |
| | | return this.projectRoleRepository; |
| | | } |
| | | |
| | | // 기본, 관리자 프로젝트 역할을 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public void addDefaultProjectRole(Project project, List<User> managers, List<User> users) { |
| | | ProjectRole projectRole = this.addProjectRole(project, "기본 프로젝트 역할", ProjectRole.TYPE_DEFAULT, Permission.ROLE_TYPE_PROJECT_JOIN); |
| | | ProjectRole managerProjectRole = this.addProjectRole(project, "프로젝트 관리자 역할", ProjectRole.TYPE_MANAGER, Permission.ROLE_TYPE_PROJECT_MANAGER); |
| | | // 프로젝트 관리자 저장 |
| | | this.projectRoleAssociatedUser(managers, managerProjectRole); |
| | | // 프로젝트 일반 사용자 저장 |
| | | this.projectRoleAssociatedUser(users, projectRole); |
| | | |
| | | this.projectRoleRepository.flush(); |
| | | } |
| | | |
| | | // 프로젝트 역할가 사용자 연결 |
| | | private void projectRoleAssociatedUser(List<User> users, ProjectRole projectRole) { |
| | | for (User user : users) { |
| | | this.addDefaultProjectRoleAssociatedUser(projectRole, user); |
| | | } |
| | | } |
| | | |
| | | // 해당 역할과 사용자를 연결시킨다. |
| | | private void addDefaultProjectRoleAssociatedUser(ProjectRole projectRole, User user) { |
| | | ProjectRoleUser projectRoleUser = this.projectRoleUserService.findByProjectRoleIdAndUserId(projectRole.getId(), user.getId()); |
| | | |
| | | if (projectRoleUser == null) { |
| | | // 프로젝트 관리자 - 기본 프로젝트 역할에 추가. |
| | | user.addProjectRole(projectRole); |
| | | } |
| | | } |
| | | |
| | | // 프로젝트 역할을 생성한다. |
| | | private ProjectRole addProjectRole(Project project, String projectRoleName, String projectRoleType, String permissionType) { |
| | | ProjectRole projectRole = new ProjectRole(project, projectRoleName, projectRoleType); |
| | | this.projectRoleRepository.saveAndFlush(projectRole); |
| | | this.projectRolePermissionService.addDefaultProjectRoleAssociatedPermissions(projectRole, permissionType); |
| | | return projectRole; |
| | | } |
| | | |
| | | // 해당 프로젝트 역할을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public ProjectRole findByProjectIdAndRoleType(Long projectId, String roleType) { |
| | | ProjectRole projectRole = this.projectRoleRepository.findByProjectIdAndRoleType(projectId, roleType); |
| | | |
| | | if (projectRole == null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PROJECT_ROLE_NOT_EXIST)); |
| | | } |
| | | |
| | | return projectRole; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.ProjectRoleUserMapper; |
| | | import kr.wisestone.owl.repository.ProjectRoleUserRepository; |
| | | import kr.wisestone.owl.service.ProjectRoleService; |
| | | import kr.wisestone.owl.service.ProjectRoleUserService; |
| | | import kr.wisestone.owl.service.UserWorkspaceService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | public class ProjectRoleUserServiceImpl extends AbstractServiceImpl<ProjectRoleUser, Long, JpaRepository<ProjectRoleUser, Long>> implements ProjectRoleUserService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ProjectRoleUserServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private ProjectRoleUserRepository projectRoleUserRepository; |
| | | |
| | | @Autowired |
| | | private ProjectRoleService projectRoleService; |
| | | |
| | | @Autowired |
| | | private UserWorkspaceService userWorkspaceService; |
| | | |
| | | @Autowired |
| | | private ProjectRoleUserMapper projectRoleUserMapper; |
| | | |
| | | @Override |
| | | protected JpaRepository<ProjectRoleUser, Long> getRepository() { |
| | | return this.projectRoleUserRepository; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<ProjectRoleUser> findByProjectRoleId(Long projectRoleId) { |
| | | return this.projectRoleUserRepository.findByProjectRoleId(projectRoleId); |
| | | } |
| | | |
| | | // 해당 사용자가 특정 역할에 소속되어 있는지 확인한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public ProjectRoleUser findByProjectRoleIdAndUserId(Long projectRoleId, Long userId) { |
| | | return this.projectRoleUserRepository.findByProjectRoleIdAndUserId(projectRoleId, userId); |
| | | } |
| | | |
| | | // 업무 공간을 탈퇴한 사용자가 다른 업무 공간의 프로젝트 관리자, 일반 사용자로 있을 경우 제거한다. |
| | | @Override |
| | | @Transactional |
| | | public void withDrawWorkspaceManagerModifyProjectRole(Workspace workspace, User user) { |
| | | List<UserWorkspace> userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), true); |
| | | |
| | | if (userWorkspaces.size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.USER_WORKSPACE_MANAGER_NOT_EXIST)); |
| | | } |
| | | |
| | | User workspaceManager = userWorkspaces.get(0).getUser(); |
| | | |
| | | for (Project project : workspace.getProjects()) { |
| | | // 일반 참여 역할 삭제 |
| | | this.removeProjectRoleUser(project, ProjectRole.TYPE_DEFAULT, user, workspaceManager); |
| | | // 프로젝트 관리자 역할 삭제 |
| | | this.removeProjectRoleUser(project, ProjectRole.TYPE_MANAGER, user, workspaceManager); |
| | | } |
| | | } |
| | | |
| | | // 프로젝트 역할 연결 정보에서 탈퇴하는 사용자를 제거한다. |
| | | private void removeProjectRoleUser(Project project, String roleType, User user, User workspaceManager) { |
| | | ProjectRole projectRole = this.projectRoleService.findByProjectIdAndRoleType(project.getId(), roleType); |
| | | |
| | | // 프로젝트 관리자 역할일 때 |
| | | if (roleType.equals(ProjectRole.TYPE_MANAGER)) { |
| | | // 프로젝트 관리자 연결 정보 |
| | | List<ProjectRoleUser> projectRoleUsers = this.findByProjectRoleId(projectRole.getId()); |
| | | boolean existManager = false; |
| | | |
| | | // 탈퇴한 사용자가 프로젝트 관리자 여부 확인 |
| | | for (ProjectRoleUser projectRoleUser : projectRoleUsers) { |
| | | if (projectRoleUser.getUser().getId().equals(user.getId())) { |
| | | existManager = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (existManager) { |
| | | // 업무 공간 관리자가 일반 사용자 역할에 존재할 수 있으므로 제거 로직 수행 |
| | | this.removeProjectRoleUser(project, ProjectRole.TYPE_DEFAULT, workspaceManager, null); |
| | | // 업무 공간 관리자에게 프로젝트 관리자 역할 부여 |
| | | List<Map<String, Long>> projectRoleUserMaps = Lists.newArrayList(); |
| | | Map<String, Long> projectRoleUserMap = new HashMap<>(); |
| | | projectRoleUserMap.put("projectRoleId", projectRole.getId()); |
| | | projectRoleUserMap.put("userId", workspaceManager.getId()); |
| | | projectRoleUserMap.put("registerId", this.webAppUtil.getLoginId()); |
| | | projectRoleUserMaps.add(projectRoleUserMap); |
| | | // 업무 공간 관리자를 프로젝트 관리자로 지정 |
| | | this.projectRoleUserMapper.insertProjectRoleUser(projectRoleUserMaps); |
| | | |
| | | /*workspaceManager.addProjectRole(projectRole);*/ |
| | | } |
| | | } |
| | | |
| | | Map<String, Long> deleteProjectRoleUserMap = new HashMap<>(); |
| | | deleteProjectRoleUserMap.put("projectRoleId", projectRole.getId()); |
| | | deleteProjectRoleUserMap.put("userId", user.getId()); |
| | | // 탈퇴한 사용자는 프로젝트 역할 연결 정보 삭제 |
| | | this.projectRoleUserMapper.deleteProjectRoleUser(deleteProjectRoleUserMap); |
| | | |
| | | // 탈퇴한 사용자는 프로젝트 역할 연결 정보 삭제 |
| | | // user.removeProjectRole(projectRole); |
| | | } |
| | | |
| | | // 프로젝트에 참여하는 사용자, 프로젝트 관리자를 파라미터에 따라 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Map<String, Object>> findProjectRoleUser(Map<String, Object> projectRoleUserMap) { |
| | | return this.projectRoleUserMapper.findProjectRoleUser(projectRoleUserMap); |
| | | } |
| | | |
| | | // 프로젝트 관리자 여부를 확인한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public boolean checkProjectManager(Project project) { |
| | | ProjectRole projectManagerRole = this.projectRoleService.findByProjectIdAndRoleType(project.getId(), ProjectRole.TYPE_MANAGER); |
| | | // 해당 사용자가 특정 역할에 소속되어 있는지 확인한다. |
| | | ProjectRoleUser projectRoleUser = this.findByProjectRoleIdAndUserId(projectManagerRole.getId(), this.webAppUtil.getLoginId()); |
| | | |
| | | return projectRoleUser != null; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.common.ExcelConditionCheck; |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.domain.enumType.EmailType; |
| | | import kr.wisestone.owl.domain.enumType.ProjectType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.ProjectMapper; |
| | | import kr.wisestone.owl.repository.ProjectClosureRepository; |
| | | import kr.wisestone.owl.repository.ProjectRepository; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.util.CommonUtil; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.DateUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.ProjectForm; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.*; |
| | | |
| | | @Service |
| | | public class ProjectServiceImpl extends AbstractServiceImpl<Project, Long, JpaRepository<Project, Long>> implements ProjectService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ProjectServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private ProjectRepository projectRepository; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | |
| | | @Autowired |
| | | private ProjectRoleService projectRoleService; |
| | | |
| | | @Autowired |
| | | private WorkflowStatusService workflowStatusService; |
| | | |
| | | @Autowired |
| | | private WorkspaceService workspaceService; |
| | | |
| | | @Autowired |
| | | private UserWorkspaceService userWorkspaceService; |
| | | |
| | | @Autowired |
| | | private SystemEmailService systemEmailService; |
| | | |
| | | @Autowired |
| | | private ProjectRoleUserService projectRoleUserService; |
| | | |
| | | @Autowired |
| | | private AttachedFileService attachedFileService; |
| | | |
| | | @Autowired |
| | | private IssueService issueService; |
| | | |
| | | @Autowired |
| | | private IssueUserService issueUserService; |
| | | |
| | | @Autowired |
| | | private IssueNumberGeneratorService issueNumberGeneratorService; |
| | | |
| | | @Autowired |
| | | private ProjectClosureRepository projectClosureRepository; |
| | | |
| | | @Autowired |
| | | private ProjectMapper projectMapper; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | @Autowired |
| | | private ExcelConditionCheck excelConditionCheck; |
| | | |
| | | @Override |
| | | protected JpaRepository<Project, Long> getRepository() { |
| | | return this.projectRepository; |
| | | } |
| | | |
| | | // 기본으로 제공되는 프로젝트를 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public Project addDefaultProject(User user, Workspace workspace) { |
| | | Project project = new Project(); |
| | | project.setName(this.messageAccessor.message("common.issueManagementProject")); // 이슈 관리 프로젝트 |
| | | project.setProjectKey("BTS"); |
| | | project.setStatus(Project.PROJECT_OPEN); |
| | | project.setDescription(this.messageAccessor.message("common.intoTheSystemIssueManagementProject")); // 시스템에서 기본으로 제공되는 이슈 관리 프로젝트입니다. |
| | | project.setStartDate(DateUtil.convertDateToYYYYMMDD(new Date())); |
| | | project.setEndDate(DateUtil.convertDateToYYYYMMDD(DateUtil.addDays(new Date(), 3650))); |
| | | // 기본으로 생성되는 프로젝트의 유형은 BTS |
| | | project.setProjectType(ProjectType.BTS_PROJECT); |
| | | project.setWorkspace(workspace); |
| | | project.setDefaultYn(true); |
| | | this.projectRepository.saveAndFlush(project); |
| | | // 프로젝트 기본 역할과 관리자 역할을 생성한다. 관리자는 생성한 사용자 |
| | | this.projectRoleService.addDefaultProjectRole(project, Lists.newArrayList(user), Lists.newArrayList()); |
| | | // 각 프로젝트의 이슈 번호를 자동으로 생성한다. |
| | | this.issueNumberGeneratorService.generateIssueNumber(project); |
| | | |
| | | // 기본으로 생성되는 프로젝트의 유형은 개발 프로젝트 |
| | | this.workflowStatusService.addDefaultWorkflowStatus(project, ProjectType.RMS_PROJECT); |
| | | |
| | | return project; |
| | | } |
| | | |
| | | // 프로젝트를 사용자가 생성한다. |
| | | @Transactional |
| | | @Override |
| | | public Project addProject(ProjectForm projectForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 이름 유효성 체크 |
| | | this.verifyName(projectForm.getName(), null); |
| | | // 키 유효성 체크 |
| | | this.checkDuplicateProjectKey(projectForm.getProjectKey()); |
| | | // 상태 체크 |
| | | this.verifyProjectStatus(projectForm.getStatus()); |
| | | // 날짜 유효성 체크 |
| | | this.checkStartEndDate(projectForm.getStartDate(), projectForm.getEndDate()); |
| | | // 관리자 유효성 체크 |
| | | this.verifyManager(projectForm.getManagerIds()); |
| | | |
| | | Project project = ConvertUtil.copyProperties(projectForm, Project.class, "projectType"); |
| | | project.setProjectType(ProjectType.valueOf(projectForm.getProjectType())); |
| | | Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | project.setWorkspace(workspace); |
| | | |
| | | this.projectRepository.saveAndFlush(project); |
| | | // 상위프로젝트 넣기 |
| | | SetParentProject(projectForm.getParentProjectId(), project); |
| | | |
| | | // 각 프로젝트의 이슈 번호를 자동으로 생성한다. |
| | | this.issueNumberGeneratorService.generateIssueNumber(project); |
| | | // 일반 사용자 및 관리자를 등록하고 사용자들에게 해당 역할을 배정한다. |
| | | this.registerManagerAndUser(projectForm, project); |
| | | |
| | | // 프로젝트 유형에 따른 워크플로우 생성 |
| | | this.workflowStatusService.addDefaultWorkflowStatus(project, ProjectType.valueOf(projectForm.getProjectType())); |
| | | |
| | | return project; |
| | | } |
| | | |
| | | // 일반 사용자 및 관리자를 등록하고 사용자들에게 해당 역할을 배정한다. |
| | | private void registerManagerAndUser(ProjectForm projectForm, Project project) { |
| | | List<User> managers = Lists.newArrayList(); |
| | | // 관리자 등록 |
| | | for (Long managerId : projectForm.getManagerIds()) { |
| | | User user = this.userService.getUser(managerId); |
| | | managers.add(user); |
| | | } |
| | | List<User> users = Lists.newArrayList(); |
| | | List<String> sendEmails = Lists.newArrayList(); // 메일 대상자 |
| | | |
| | | // 일반 사용자 등록 |
| | | for (Long userId : projectForm.getUserIds()) { |
| | | User user = this.userService.getUser(userId); |
| | | users.add(user); |
| | | sendEmails.add(user.getAccount()); |
| | | } |
| | | |
| | | // 기본, 관리자 프로젝트 역할을 생성하고 사용자를 해당 역할에 배정한다. |
| | | this.projectRoleService.addDefaultProjectRole(project, managers, users); |
| | | |
| | | // 프로젝트 참여자들에게 이메일 발송을 예약한다. |
| | | Map<String, Object> projectMap = new HashMap<>(); |
| | | projectMap.put("workspaceName", project.getWorkspace().getName()); |
| | | projectMap.put("projectName", project.getName()); |
| | | projectMap.put("registerDate", DateUtil.convertDateToStr(new Date())); |
| | | |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | stringBuilder.append(managers.get(0).getName()); |
| | | stringBuilder.append("("); |
| | | stringBuilder.append(CommonUtil.decryptAES128(managers.get(0).getAccount())); |
| | | stringBuilder.append(")"); |
| | | |
| | | projectMap.put("projectManagerName", stringBuilder.toString()); |
| | | // 프로젝트 일반 참여 메일 발송 예약 |
| | | this.systemEmailService.reservationEmail(sendEmails.toArray(new String[sendEmails.size()]), EmailType.PROJECT_DEFAULT_INCLUDE, projectMap); |
| | | } |
| | | |
| | | |
| | | // 이름 유효성 체크 |
| | | private void verifyName(String name, Long id) { |
| | | if (StringUtils.isEmpty(name)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_NAME)); |
| | | } |
| | | |
| | | if (name.length() > 50) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NAME_MAX_LENGTH_OUT)); |
| | | } |
| | | |
| | | Project project; |
| | | |
| | | Long workspaceId = this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId(); |
| | | |
| | | if (id == null) { |
| | | project = this.projectRepository.findByNameAndWorkspaceId(name, workspaceId); |
| | | } |
| | | else { |
| | | project = this.projectRepository.findByNameAndWorkspaceIdAndIdNot(name, workspaceId, id); |
| | | } |
| | | |
| | | if (project != null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_USED_NAME)); |
| | | } |
| | | } |
| | | |
| | | // 키 유효성 체크 |
| | | private void checkDuplicateProjectKey(String projectKey) { |
| | | if (StringUtils.isEmpty(projectKey)) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PROJECT_KEY_NOT_EXIST)); |
| | | } |
| | | |
| | | |
| | | if (projectKey.length() > 10) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PROJECT_OVER_LENGTH_PROJECT_KEY)); |
| | | } |
| | | |
| | | Project project = this.findByProjectKey(projectKey); |
| | | |
| | | if (project != null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PROJECT_USED_PROJECT_KEY)); |
| | | } |
| | | } |
| | | |
| | | // 날짜 유효성 체크 |
| | | private void checkStartEndDate(String startDate, String endDate) { |
| | | if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.DATE_NOT_EXIST)); |
| | | } |
| | | |
| | | Date start = DateUtil.convertStrToDate(startDate, "yyyy-MM-dd"); |
| | | Date end = DateUtil.convertStrToDate(endDate, "yyyy-MM-dd"); |
| | | if (start.getTime() > end.getTime()) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.DATE_PICKER_NOT_AVAILABLE)); |
| | | } |
| | | } |
| | | |
| | | // 관리자 유효성 체크 |
| | | private void verifyManager(List<Long> managerIds) { |
| | | if (managerIds.isEmpty()) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_MANAGER)); |
| | | } |
| | | } |
| | | |
| | | // 상태 체크 |
| | | private void verifyProjectStatus(String projectStatus) { |
| | | if (StringUtils.isEmpty(projectStatus)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_STATUS)); |
| | | } |
| | | } |
| | | |
| | | // 프로젝트 목록을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<ProjectVo> findProject(Map<String, Object> resJsonData, |
| | | ProjectCondition condition, Pageable pageable) { |
| | | |
| | | condition.setPage(pageable.getPageNumber() * pageable.getPageSize()); |
| | | condition.setPageSize(pageable.getPageSize()); |
| | | condition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | |
| | | List<Map<String, Object>> results; |
| | | Long totalCount; |
| | | |
| | | if (condition.getWorkspaceManager()) { |
| | | // 업무공간 관리자일 경우 모든 프로젝트가 표시되어야 한다. |
| | | // 관리자일 때 |
| | | if (this.userWorkspaceService.checkWorkspaceManager()) { |
| | | results = this.projectMapper.findByWorkspaceManager(condition); |
| | | totalCount = this.projectMapper.countByWorkspaceManager(condition); |
| | | } |
| | | else { |
| | | results = this.projectMapper.find(condition); |
| | | totalCount = this.projectMapper.count(condition); |
| | | } |
| | | } |
| | | else { |
| | | results = this.projectMapper.find(condition); |
| | | totalCount = this.projectMapper.count(condition); |
| | | } |
| | | |
| | | int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; |
| | | // 프로젝트 조회 결과를 ProjectVos 로 변환한다. - 관리자, 일반 사용자 정보 추가 |
| | | List<ProjectVo> projectVos = this.makeProjectVos(results); |
| | | this.setChildrenProject(projectVos); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, projectVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | |
| | | return projectVos; |
| | | } |
| | | |
| | | void setChildrenProject(List<ProjectVo> projectVos) { |
| | | int projectCount = projectVos.size(); |
| | | for (int i=0; i< projectCount; i++) { |
| | | ProjectVo projectVo = projectVos.get(i); |
| | | List<Map<String, Object>> children = this.projectMapper.findChildrenProject(projectVo.getId()); |
| | | |
| | | if (children != null && children.size() > 0) { |
| | | List<ProjectVo> childrenVo = this.makeProjectVos(children); |
| | | projectVo.setChildProjects(childrenVo); |
| | | setChildrenProject(childrenVo); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 프로젝트 조회 결과를 ProjectVos 로 변환한다. |
| | | private List<ProjectVo> makeProjectByVos(List<Map<String, Object>> results) { |
| | | List<ProjectVo> projectVos = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | ProjectVo projectVo = ConvertUtil.convertMapToClass(result, ProjectVo.class); |
| | | projectVos.add(projectVo); |
| | | } |
| | | |
| | | return projectVos; |
| | | } |
| | | |
| | | |
| | | // 프로젝트 조회 결과를 ProjectVos 로 변환한다. - 관리자, 일반 사용자 정보 추가 |
| | | private List<ProjectVo> makeProjectVos(List<Map<String, Object>> results) { |
| | | List<ProjectVo> projectVos = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | ProjectVo projectVo = ConvertUtil.convertMapToClass(result, ProjectVo.class); |
| | | // 프로젝트에 참여하는 사용자를 셋팅한다. - 관리자 / 일반 사용자 |
| | | this.setProjectUser(projectVo, true); |
| | | this.setProjectUser(projectVo, false); |
| | | // 업무공간 담당자는 모든 프로젝트를 수정/삭제할 수 있어야 한다. |
| | | if (this.userWorkspaceService.checkWorkspaceManager()) { |
| | | projectVo.setModifyPermissionCheck(true); |
| | | } |
| | | projectVos.add(projectVo); |
| | | } |
| | | |
| | | return projectVos; |
| | | } |
| | | |
| | | // 관리자, 일반 사용자를 조건에 따라 찾아준다. |
| | | private void setProjectUser(ProjectVo projectVo, Boolean findProjectManager) { |
| | | Map<String, Object> projectRoleUserMap = new HashMap<>(); |
| | | projectRoleUserMap.put("id", projectVo.getId()); |
| | | |
| | | if (findProjectManager) { |
| | | projectRoleUserMap.put("statuses", Lists.newArrayList("02")); // 관리자 셋팅 |
| | | } |
| | | else { |
| | | projectRoleUserMap.put("statuses", Lists.newArrayList("01")); // 일반 사용자 셋팅 |
| | | } |
| | | |
| | | // 사용자 정보 셋팅 |
| | | List<Map<String, Object>> projectRoleUsers = this.projectRoleUserService.findProjectRoleUser(projectRoleUserMap); |
| | | |
| | | if (projectRoleUsers != null && !projectRoleUsers.isEmpty()) { |
| | | List<UserVo> userVos = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> projectRoleUser : projectRoleUsers) { |
| | | UserVo userVo = ConvertUtil.convertMapToClass(projectRoleUser, UserVo.class); |
| | | userVo.setByName(userVo.getName() + "(" + CommonUtil.decryptAES128(userVo.getAccount()) + ")"); |
| | | userVo.setAccount(CommonUtil.decryptAES128(userVo.getAccount())); |
| | | // 현재 로그인한 사용자가 담당자일 경우 수정 권한을 준다. |
| | | if (userVo.getId().equals(this.webAppUtil.getLoginId()) && findProjectManager) { |
| | | projectVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | userVos.add(userVo); |
| | | } |
| | | |
| | | if (findProjectManager) { |
| | | projectVo.setProjectManagerVos(userVos); |
| | | } |
| | | else { |
| | | projectVo.setProjectUserVos(userVos); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 프로젝트 상세 정보를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void detailProject(Map<String, Object> resJsonData, ProjectCondition projectCondition) { |
| | | ProjectVo projectVo = new ProjectVo(); |
| | | |
| | | if (projectCondition.getId() != null) { |
| | | Project project = this.getProject(projectCondition.getId()); |
| | | projectVo = ConvertUtil.copyProperties(project, ProjectVo.class); |
| | | projectVo.setProjectType(project.getProjectType().toString()); |
| | | |
| | | // 상위 프로젝트 정보 가져오기 |
| | | ProjectClosure closure = project.getParentProjectClosure(); |
| | | if (closure != null) { |
| | | ProjectVo parentProjectVo = ConvertUtil.copyProperties(closure.getParentProject(), ProjectVo.class); |
| | | projectVo.setParentProjectVo(parentProjectVo); |
| | | } |
| | | |
| | | switch (projectCondition.getDeep()) { |
| | | case "01": // 프로젝트에 참여하는 사용자, 관리자 정보를 셋팅한다. |
| | | this.setProjectUser(projectVo, true); |
| | | this.setProjectUser(projectVo, false); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, projectVo); |
| | | } |
| | | |
| | | // 프로젝트 정보를 수정한다. |
| | | @Transactional |
| | | @Override |
| | | public Project modifyProject(ProjectForm projectForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | // 이름 유효성 체크 |
| | | this.verifyName(projectForm.getName(), projectForm.getId()); |
| | | // 상태 체크 |
| | | this.verifyProjectStatus(projectForm.getStatus()); |
| | | // 날짜 유효성 체크 |
| | | this.checkStartEndDate(projectForm.getStartDate(), projectForm.getEndDate()); |
| | | // 관리자 유효성 체크 |
| | | this.verifyManager(projectForm.getManagerIds()); |
| | | |
| | | Project project = this.getProject(projectForm.getId()); |
| | | // 프로젝트 참여 사용자 |
| | | List<Long> existUserIds = this.getIncludeProjectUser(project); |
| | | |
| | | // 워크스페이스에서 기본으로 제공되는 프로젝트에 대한 체크 |
| | | this.checkDefaultProject(project, projectForm); |
| | | // 수정 권한 체크 |
| | | this.checkModifyPermission(project.getId()); |
| | | // 관리자 변경 |
| | | Map<String, Object> changeProjectManagerNotifications = this.modifyProjectManagers(project, projectForm, ProjectRole.TYPE_MANAGER); |
| | | // 일반 사용자 변경 |
| | | Map<String, Object> changeProjectUserNotifications = this.modifyProjectManagers(project, projectForm, ProjectRole.TYPE_DEFAULT); |
| | | ConvertUtil.copyProperties(projectForm, project, "id", "projectType"); |
| | | |
| | | this.projectRepository.saveAndFlush(project); |
| | | |
| | | // 상위 프로젝트 정보 저장 |
| | | SetParentProject(projectForm.getParentProjectId(), project); |
| | | |
| | | // 프로젝트에서 참여가 제외된 사용자는 이슈 담당자에서 제외한다. |
| | | // 해당 프로젝트에 참여하는 모든 사용자 조회 |
| | | // 빠진 사람이 관리하는 이슈 전체 조회 후 데이터 삭제 |
| | | List<Long> changeUserIds = this.getIncludeProjectUser(project); |
| | | |
| | | // 참여에서 제외된 사용자를 찾고 담당하고 있던 이슈에서 제외한다. |
| | | this.checkExcludeUserAndRemoveIssueAssignee(project, existUserIds, changeUserIds); |
| | | |
| | | // 관리자/일반 사용자 변경 내역을 통지한다. |
| | | this.notificationProjectRoleUser(changeProjectManagerNotifications, changeProjectUserNotifications, project); |
| | | |
| | | return project; |
| | | } |
| | | |
| | | void SetParentProject(Long parentProjectId, Project project) { |
| | | ProjectClosure projectClosure = this.projectClosureRepository.findByProjectId(project.getId()); |
| | | if (parentProjectId != null && parentProjectId > -1) { |
| | | Project parentProject = this.getProject(parentProjectId); |
| | | if (projectClosure != null) { |
| | | projectClosure.setParentProject(parentProject); |
| | | } else { |
| | | projectClosure = new ProjectClosure(project, parentProject); |
| | | } |
| | | this.projectClosureRepository.saveAndFlush(projectClosure); |
| | | } else { |
| | | if (projectClosure != null) { |
| | | this.projectClosureRepository.delete(projectClosure); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 프로젝트 참여 사용자 |
| | | private List<Long> getIncludeProjectUser(Project project) { |
| | | Set<Long> includeUserIds = new HashSet<>(); |
| | | |
| | | for (ProjectRole projectRole : project.getProjectRoles()) { |
| | | List<ProjectRoleUser> projectRoleUsers = this.projectRoleUserService.findByProjectRoleId(projectRole.getId()); |
| | | |
| | | for (ProjectRoleUser projectRoleUser : projectRoleUsers) { |
| | | includeUserIds.add(projectRoleUser.getUser().getId()); |
| | | } |
| | | } |
| | | |
| | | return Lists.newArrayList(includeUserIds); |
| | | } |
| | | |
| | | // 참여에서 제외된 사용자를 찾고 담당하고 있던 이슈에서 제외한다. |
| | | private void checkExcludeUserAndRemoveIssueAssignee(Project project, List<Long> existUserIds, List<Long> changeUserIds) { |
| | | List<Long> excludeUserIds = CommonUtil.searchChangeList(changeUserIds, existUserIds); |
| | | |
| | | if (excludeUserIds.size() > 0) { |
| | | this.issueUserService.removeIssueUser(project.getId(), excludeUserIds); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // 기본 제공되는 프로젝트의 관리자는 워크스페이스 관리자가 포함되어 있어야 한다. |
| | | private void checkDefaultProject(Project project, ProjectForm projectForm) { |
| | | if (project.getDefaultYn()) { |
| | | // 해당 프로젝트의 워크스페이스의 관리자를 찾는다. |
| | | // 기본 프로젝트는 워크스페이스 관리자가 무조건 프로젝트 관리자로 들어가 있어야 한다. |
| | | Workspace workspace = project.getWorkspace(); |
| | | List<UserWorkspace> userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), true); |
| | | |
| | | for (UserWorkspace userWorkspace : userWorkspaces) { |
| | | User workspaceManager = userWorkspace.getUser(); |
| | | boolean checkDefaultManager = false; |
| | | |
| | | for (Long managerId : projectForm.getManagerIds()) { |
| | | if (managerId.equals(workspaceManager.getId())) { |
| | | checkDefaultManager = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!checkDefaultManager) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.DEFAULT_PROJECT_MANAGER_NOT_CHANGE)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 로그인한 사용자가 관리자 역할에 소속되어 있는지 확인한다. |
| | | private void checkModifyPermission(Long projectId) { |
| | | Boolean hasPermission = Boolean.FALSE; |
| | | |
| | | // 해당 업무 공간의 관리자일 경우 권한 체크를 하지 않는다. |
| | | if (this.userWorkspaceService.checkWorkspaceManager()) { |
| | | return; |
| | | } |
| | | |
| | | // 관리자 역할 조회 |
| | | Map<String, Object> projectRoleUserMap = new HashMap<>(); |
| | | projectRoleUserMap.put("id", projectId); |
| | | projectRoleUserMap.put("statuses", Lists.newArrayList("02")); // 관리자 조회 |
| | | |
| | | List<Map<String, Object>> projectUsers = this.projectRoleUserService.findProjectRoleUser(projectRoleUserMap); |
| | | // 현재 로그인 사용자가 관리자인지 확인 |
| | | if (projectUsers != null && !projectUsers.isEmpty()) { |
| | | for (Map<String, Object> projectUser : projectUsers) { |
| | | UserVo userVo = ConvertUtil.convertMapToClass(projectUser, UserVo.class); |
| | | if (userVo.getId().equals(this.webAppUtil.getLoginId())) { |
| | | hasPermission = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!hasPermission) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_MODIFY_PERMISSION)); |
| | | } |
| | | } |
| | | |
| | | // 관리자를 변경한다. |
| | | private Map<String, Object> modifyProjectManagers(Project project, ProjectForm projectForm, String roleType) { |
| | | ProjectRole projectRole = this.projectRoleService.findByProjectIdAndRoleType(project.getId(), roleType); |
| | | List<User> oldManager = Lists.newArrayList(); |
| | | List<User> newManager = Lists.newArrayList(); |
| | | Map<String, Object> results = new HashMap<>(); |
| | | |
| | | for (ProjectRoleUser projectRoleUser : projectRole.getProjectRoleUsers()) { |
| | | User user = projectRoleUser.getUser(); |
| | | oldManager.add(user); |
| | | user.removeProjectRole(projectRole); |
| | | } |
| | | |
| | | projectRole.getProjectRoleUsers().clear(); |
| | | |
| | | // 관리자일 경우 |
| | | if (roleType.equals(ProjectRole.TYPE_MANAGER)) { |
| | | for (Long managerId : projectForm.getManagerIds()) { |
| | | User user = this.userService.getUser(managerId); |
| | | newManager.add(user); |
| | | user.addProjectRole(projectRole); |
| | | } |
| | | } |
| | | else if (roleType.equals(ProjectRole.TYPE_DEFAULT)) { |
| | | // 일반 사용자일 경우 |
| | | for (Long userId : projectForm.getUserIds()) { |
| | | User user = this.userService.getUser(userId); |
| | | newManager.add(user); |
| | | user.addProjectRole(projectRole); |
| | | } |
| | | } |
| | | |
| | | // 제외 대상자 찾기, oldManager 에는 있는데 newManager 에 없으면 제외 대상 |
| | | List<String> excludeUsers = this.systemEmailService.notificationUserChange(oldManager, newManager); |
| | | // 참여 대상자 찾기, newManager 에는 있는데 oldManager 에 없으면 초대받은 대상 |
| | | List<String> includeUsers = this.systemEmailService.notificationUserChange(newManager, oldManager); |
| | | |
| | | results.put("excludeUsers", excludeUsers); |
| | | results.put("includeUsers", includeUsers); |
| | | |
| | | return results; |
| | | |
| | | } |
| | | |
| | | // 프로젝트 참여, 제외 통지 정보를 중복으로 나가지 않도록 체크한다. |
| | | private void notificationProjectRoleUser(Map<String, Object> changeProjectManagerNotifications, Map<String, Object> changeProjectUserNotifications, Project project) { |
| | | List<String> projectManagerExcludeUsers = (List<String>) changeProjectManagerNotifications.get("excludeUsers"); // 관리자 제외 사용자 |
| | | List<String> projectManagerIncludeUsers = (List<String>) changeProjectManagerNotifications.get("includeUsers"); // 관리자 참여 사용자 |
| | | List<String> projectUserExcludeUsers = (List<String>) changeProjectUserNotifications.get("excludeUsers"); // 제외된 일반 사용자 |
| | | List<String> projectUserIncludeUsers = (List<String>) changeProjectUserNotifications.get("includeUsers"); // 참여된 일반 사용자 |
| | | Map<String, Object> projectMap = new HashMap<>(); |
| | | projectMap.put("workspaceName", project.getWorkspace().getName()); |
| | | projectMap.put("projectName", project.getName()); |
| | | projectMap.put("registerDate", DateUtil.convertDateToStr(new Date())); |
| | | |
| | | Map<String, Object> projectRoleUserMap = new HashMap<>(); |
| | | projectRoleUserMap.put("id", project.getId()); |
| | | projectRoleUserMap.put("statuses", Lists.newArrayList("02")); // 관리자 조회 |
| | | |
| | | // 관리자 정보 셋팅 |
| | | List<Map<String, Object>> projectRoleUsers = this.projectRoleUserService.findProjectRoleUser(projectRoleUserMap); |
| | | |
| | | if (projectRoleUsers != null && !projectRoleUsers.isEmpty()) { |
| | | for (Map<String, Object> projectRoleUser : projectRoleUsers) { |
| | | UserVo userVo = ConvertUtil.convertMapToClass(projectRoleUser, UserVo.class); |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | stringBuilder.append(userVo.getName()); |
| | | stringBuilder.append("("); |
| | | stringBuilder.append(CommonUtil.decryptAES128(userVo.getAccount())); |
| | | stringBuilder.append(")"); |
| | | |
| | | projectMap.put("projectManagerName", stringBuilder.toString()); |
| | | } |
| | | } |
| | | |
| | | // 프로젝트 관리자에서 제외되었으면서 프로젝트 일반 사용자로 들어간 경우 |
| | | List<String> excludeManagerAndIncludeUser = Lists.newArrayList(); |
| | | |
| | | for (String projectManagerExcludeUserEmail : projectManagerExcludeUsers) { |
| | | for (String projectUserIncludeUserEmail : projectUserIncludeUsers) { |
| | | if (projectManagerExcludeUserEmail.equals(projectUserIncludeUserEmail)) { |
| | | excludeManagerAndIncludeUser.add(projectManagerExcludeUserEmail); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 일반 사용자에서 제외되었으면서 프로젝트 관리자로 들어간 경우 |
| | | List<String> excludeUserAndIncludeManager = Lists.newArrayList(); |
| | | |
| | | for (String projectUserExcludeUserEmail : projectUserExcludeUsers) { |
| | | for (String projectManagerIncludeUserEmail : projectManagerIncludeUsers) { |
| | | if (projectUserExcludeUserEmail.equals(projectManagerIncludeUserEmail)) { |
| | | excludeUserAndIncludeManager.add(projectManagerIncludeUserEmail); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 프로젝트 관리자에서 제외되었으면서 프로젝트 일반 사용자로 들어간 경우 |
| | | this.sendEmailProjectRoleChange(excludeManagerAndIncludeUser, EmailType.PROJECT_MANAGER_EXCLUDE_AND_PROJECT_DEFAULT_INCLUDE, projectMap); |
| | | // 일반 사용자에서 제외되었으면서 프로젝트 관리자로 들어간 경우 |
| | | this.sendEmailProjectRoleChange(excludeUserAndIncludeManager, EmailType.PROJECT_DEFAULT_EXCLUDE_AND_PROJECT_MANAGER_INCLUDE, projectMap); |
| | | // 관리자 제외 메일 최종 |
| | | this.sendEmailProjectRoleChange(this.checkDuplicationEmails(projectManagerExcludeUsers, excludeManagerAndIncludeUser, excludeUserAndIncludeManager), EmailType.PROJECT_MANAGER_EXCLUDE, projectMap); |
| | | // 관리차 참여 메일 최종 |
| | | this.sendEmailProjectRoleChange(this.checkDuplicationEmails(projectManagerIncludeUsers, excludeManagerAndIncludeUser, excludeUserAndIncludeManager), EmailType.PROJECT_MANAGER_INCLUDE, projectMap); |
| | | // 일반 사용자 제외 메일 최종 |
| | | this.sendEmailProjectRoleChange(this.checkDuplicationEmails(projectUserExcludeUsers, excludeManagerAndIncludeUser, excludeUserAndIncludeManager), EmailType.PROJECT_DEFAULT_EXCLUDE, projectMap); |
| | | // 일반 사용자 참여 메일 최종 |
| | | this.sendEmailProjectRoleChange(this.checkDuplicationEmails(projectUserIncludeUsers, excludeManagerAndIncludeUser, excludeUserAndIncludeManager), EmailType.PROJECT_DEFAULT_INCLUDE, projectMap); |
| | | } |
| | | |
| | | // 중복으로 나가는 메일이 있는지 체크한다. |
| | | private List<String> checkDuplicationEmails(List<String> checkEmails, List<String> excludeManagerAndIncludeUser, List<String> excludeUserAndIncludeManager) { |
| | | List<String> sendProjectManagerExcludeUserEmails = Lists.newArrayList(); |
| | | |
| | | for (String projectManagerExcludeUserEmail : checkEmails) { |
| | | boolean sendEmail = true; |
| | | // 관리자 제외 메일을 보내려는데 중복되는 메일이 나갈지 판단한다. |
| | | for (String excludeManagerAndIncludeUserEmail : excludeManagerAndIncludeUser) { |
| | | if (excludeManagerAndIncludeUserEmail.equals(projectManagerExcludeUserEmail)) { |
| | | sendEmail = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 관리자 제외 메일을 보내려는데 중복되는 메일이 나갈지 판단한다. |
| | | for (String excludeUserAndIncludeManagerEmail : excludeUserAndIncludeManager) { |
| | | if (excludeUserAndIncludeManagerEmail.equals(projectManagerExcludeUserEmail)) { |
| | | sendEmail = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (sendEmail) { |
| | | sendProjectManagerExcludeUserEmails.add(projectManagerExcludeUserEmail); |
| | | } |
| | | } |
| | | |
| | | return sendProjectManagerExcludeUserEmails; |
| | | } |
| | | |
| | | // 프로젝트 참여가 변경된 대상자에게 이메일을 보낸다. |
| | | private void sendEmailProjectRoleChange(List<String> sendEmails, EmailType emailType, Map<String, Object> params) { |
| | | String[] sendUsers = sendEmails.toArray(new String[sendEmails.size()]); |
| | | |
| | | if (sendUsers.length > 0) { |
| | | // 마지막 접근 프로젝트에서 제외되었을 때 화면 새로고침을 한다. |
| | | switch (emailType) { |
| | | case PROJECT_DEFAULT_EXCLUDE: |
| | | case PROJECT_MANAGER_EXCLUDE: |
| | | this.updateProjectExcludeUserLastWorkspaceId(sendUsers, params); |
| | | break; |
| | | } |
| | | |
| | | this.systemEmailService.reservationEmail(sendUsers, emailType, params); |
| | | } |
| | | } |
| | | |
| | | // 접속중인 사용자중 제외당한 사용자가 해당 프로젝트를 보고있으면 경고창을 표시하고 화면을 새로고침해준다. |
| | | private void updateProjectExcludeUserLastWorkspaceId(String[] sendUsers, Map<String, Object> params) { |
| | | /* List<UserVo> activeLoginUserVos = this.webSocketSessionService.getActiveUserVos(); |
| | | Long projectId = MapUtil.getLong(params, "projectId");*/ |
| | | |
| | | /*for (String email : sendUsers) { |
| | | // 접속중이 아니어도 마지막 정보는 업데이트한다. |
| | | User user = this.userService.findByAccount(email); |
| | | |
| | | if (user != null && projectId != null) { |
| | | // 해당 사용자가 마지막으로 접근한 프로젝트가 제외당한 프로젝트라면 워크스페이스 정보를 초기화한다. |
| | | if (projectId.equals(user.getLastProjectId())) { |
| | | // 자신의 마지막 접근 workspace & project 정보를 본인이 관리하는 워크스페이스의 기본 프로젝트로 초기화한다. |
| | | this.userService.initLastWorkspaceIdAndLastProjectId(user); |
| | | |
| | | for (UserVo userVo : activeLoginUserVos) { |
| | | // 접속중인 사용자에게만 웹 소켓 업데이트 시작. |
| | | if (userVo.getAccount().equals(email)) { |
| | | this.simpMessagingTemplate.convertAndSendToUser(email, "/notification/project-exclude", this.messageAccessor.getMessage(MsgConstants.PROJECT_EXCLUDE), params); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }*/ |
| | | } |
| | | |
| | | // 프로젝트 키로 프로젝트를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Project findByProjectKey(String projectKey) { |
| | | return this.projectRepository.findByProjectKeyAndWorkspaceId(projectKey, this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | |
| | | // 프로젝트 아이디로 프로젝트를 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public Project getProject(Long id) { |
| | | if (id == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_EXIST)); |
| | | } |
| | | |
| | | Project project = this.findOne(id); |
| | | |
| | | if (project == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_EXIST)); |
| | | } |
| | | |
| | | return project; |
| | | } |
| | | |
| | | // 프로젝트를 삭제한다. |
| | | @Override |
| | | @Transactional |
| | | public void removeProjects(ProjectForm projectForm) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | |
| | | if (projectForm.getRemoveIds().size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_REMOVE_NOT_SELECT)); |
| | | } |
| | | |
| | | for (Long projectId : projectForm.getRemoveIds()) { |
| | | this.removeProjects(projectId); |
| | | } |
| | | |
| | | this.projectRepository.flush(); |
| | | } |
| | | |
| | | private void removeProjects(Long projectId) { |
| | | Project project = this.getProject(projectId); |
| | | // 기본 프로젝트는 삭제 금지 |
| | | if (project.getDefaultYn()) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.DEFAULT_PROJECT_NOT_REMOVE)); |
| | | } |
| | | |
| | | // 로그인한 사용자가 관리자 역할에 소속되어 있는지 확인한다. |
| | | this.checkModifyPermission(project.getId()); |
| | | |
| | | List<String> sendEmails = Lists.newArrayList(); |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("projectId", projectId); |
| | | |
| | | // 해당 프로젝트에 참여하고 있는 사용자는 모두 프로젝트 제외 알림 메일을 해준다. |
| | | for (ProjectRole projectRole : project.getProjectRoles()) { |
| | | for (ProjectRoleUser projectRoleUser : projectRole.getProjectRoleUsers()) { |
| | | sendEmails.add(projectRoleUser.getUser().getAccount()); |
| | | } |
| | | } |
| | | |
| | | String[] sendUsers = sendEmails.toArray(new String[sendEmails.size()]); |
| | | this.updateProjectExcludeUserLastWorkspaceId(sendUsers, params); |
| | | |
| | | // 프로젝트에 있는 모든 이슈 정보를 조회한다. |
| | | List<Long> issueIds = this.issueService.findByProjectId(projectId); |
| | | List<Long> projectRoleIds = Lists.newArrayList(); |
| | | for (ProjectRole projectRole : project.getProjectRoles()) { |
| | | projectRoleIds.add(projectRole.getId()); |
| | | } |
| | | |
| | | params.put("issueIds", issueIds); |
| | | params.put("projectRoleIds", projectRoleIds); |
| | | |
| | | // 프로젝트에 있는 모든 정보를 삭제한다. |
| | | this.projectMapper.deleteProject(params); |
| | | |
| | | // 프로젝트 삭제시 이슈에 첨부된 파일을 시스템에서 삭제한다. |
| | | this.attachedFileService.deleteIssueCascadeAttachedFile(issueIds, project.getWorkspace()); |
| | | this.projectRepository.flush(); |
| | | |
| | | // this.projectRepository.delete(project.getId()); |
| | | } |
| | | |
| | | // 워크스페이스에 있는 모든 프로젝트를 조회한다. 이슈 엑셀 import 에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Project> findByWorkspaceId() { |
| | | return this.projectRepository.findByWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | } |
| | | |
| | | // 현재 접근한 업무공간에서 참여하고 있는 프로젝트를 조회한다. - 대시보드, 이슈 목록에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<Map<String, Object>> findByWorkspaceIdAndIncludeProject(List<String> statuses, String projectType) { |
| | | ProjectCondition projectCondition = new ProjectCondition(); |
| | | projectCondition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | projectCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | projectCondition.setProjectType(projectType); |
| | | projectCondition.setStatuses(statuses); |
| | | |
| | | return this.projectMapper.findByWorkspaceIdAndIncludeProject(projectCondition); |
| | | } |
| | | |
| | | // 현재 접근한 업구공간에서 참여하고 있는 프로젝트를 조회한다(하위프로젝트 미포함) |
| | | @Override |
| | | public List<Map<String, Object>> findByWorkspaceIdAndIncludeProject(ProjectCondition projectCondition) { |
| | | projectCondition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | projectCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | return this.projectMapper.findByWorkspaceIdAndIncludeProject(projectCondition); |
| | | } |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> findByWorkspaceIdAndIncludeProjectAll(List<String> statuses, String projectType) { |
| | | ProjectCondition projectCondition = new ProjectCondition(); |
| | | projectCondition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | projectCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | projectCondition.setProjectType(projectType); |
| | | projectCondition.setStatuses(statuses); |
| | | |
| | | return this.projectMapper.findByWorkspaceIdAndIncludeProjectAll(projectCondition); |
| | | } |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> findByWorkspaceManagerAll() { |
| | | ProjectCondition projectCondition = new ProjectCondition(); |
| | | projectCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | return this.projectMapper.findByWorkspaceManagerAll(projectCondition); |
| | | } |
| | | |
| | | // 현재 접근한 업구공간에서 참여하고 있는 프로젝트를 조회한다(하위프로젝트 포함) |
| | | @Override |
| | | public List<Map<String, Object>> findByWorkspaceIdAndIncludeProjectAll(ProjectCondition projectCondition) { |
| | | projectCondition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | projectCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | return this.projectMapper.findByWorkspaceIdAndIncludeProjectAll(projectCondition); |
| | | } |
| | | |
| | | // 현재 접근한 업무공간에서 참여하고 있는 프로젝트를 조회한다. - 상단 프로젝트 목록에서 사용 |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public List<ProjectVo> findByIncludeProject(List<String> statuses, String projectType) { |
| | | ProjectCondition projectCondition = new ProjectCondition(); |
| | | projectCondition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | projectCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | projectCondition.setProjectType(projectType); |
| | | projectCondition.setStatuses(statuses); |
| | | |
| | | List<Map<String, Object>> results; |
| | | |
| | | if (this.userWorkspaceService.checkWorkspaceManager()) { |
| | | results = this.projectMapper.findByWorkspaceManager(projectCondition); |
| | | } else { |
| | | results = this.projectMapper.findByWorkspaceIdAndIncludeProject(projectCondition); |
| | | } |
| | | List<ProjectVo> projectVos = this.makeProjectByVos(results); |
| | | this.setChildrenProject(projectVos); |
| | | |
| | | return projectVos; |
| | | } |
| | | |
| | | // 프로젝트 목록을 엑셀로 다운로드 한다. |
| | | @Override |
| | | @Transactional |
| | | public ModelAndView downloadExcel(HttpServletRequest request, Model model) { |
| | | // 사용 공간에서 로그인한 사용자가 비활성인지 확인하고 비활성일 경우 엑셀 다운로드를 금지한다. |
| | | ModelAndView modelAndView = this.workspaceService.checkUseExcelDownload(model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | Map<String, Object> conditions = new HashMap<>(); |
| | | // 엑셀 다운로드에 필요한 검색 조건 정보를 추출하고 검색 조건 추출에 오류가 발생하면 경고를 표시해준다. |
| | | modelAndView = this.excelConditionCheck.checkCondition(conditions, request, model); |
| | | if (modelAndView != null) { |
| | | return modelAndView; |
| | | } |
| | | |
| | | ProjectCondition projectCondition = ProjectCondition.make(conditions); |
| | | projectCondition.setLoginUserId(this.webAppUtil.getLoginId()); |
| | | projectCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | List<Map<String, Object>> results = this.projectMapper.find(projectCondition); |
| | | // 프로젝트 조회 결과를 ProjectVos 로 변환한다. - 관리자, 일반 사용자 정보 추가 |
| | | List<ProjectVo> projectVos = this.makeProjectVos(results); |
| | | ExportExcelVo excelInfo = new ExportExcelVo(); |
| | | excelInfo.setFileName(this.messageAccessor.message("common.projectList")); // 프로젝트 목록 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("statusName", this.messageAccessor.message("common.status"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 상태 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("name", this.messageAccessor.message("common.project"), 40, ExportExcelAttrVo.ALIGN_LEFT)); // 프로젝트 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("manager", this.messageAccessor.message("common.admin"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 관리자 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("members", this.messageAccessor.message("common.teamMember"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 팀원 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("period", this.messageAccessor.message("common.period"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 기간 |
| | | excelInfo.addAttrInfos(new ExportExcelAttrVo("projectKey", this.messageAccessor.message("common.projectKey"), 6, ExportExcelAttrVo.ALIGN_CENTER)); // 프로젝트 키 |
| | | // 엑셀에 넣을 데이터 - ProjectVos 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | excelInfo.setDatas(this.convertExcelViewToProjectVos(projectVos)); |
| | | |
| | | model.addAttribute(Constants.EXCEL, excelInfo); |
| | | return new ModelAndView(this.excelView); |
| | | } |
| | | |
| | | // ProjectVo 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다. |
| | | private List<Map<String, String>> convertExcelViewToProjectVos(List<ProjectVo> projectVos) { |
| | | List<Map<String, String>> results = Lists.newArrayList(); |
| | | |
| | | for (ProjectVo projectVo : projectVos) { |
| | | Map<String, String> result = new HashMap<>(); |
| | | |
| | | String projectStatusName = ""; |
| | | |
| | | switch (projectVo.getStatus()) { |
| | | case Project.PROJECT_READY: |
| | | projectStatusName = this.messageAccessor.message("common.wait"); // 대기 |
| | | break; |
| | | case Project.PROJECT_OPEN: |
| | | projectStatusName = this.messageAccessor.message("common.progress"); // 진행 |
| | | break; |
| | | case Project.PROJECT_CLOSE: |
| | | projectStatusName = this.messageAccessor.message("common.end"); // 종료 |
| | | break; |
| | | } |
| | | |
| | | result.put("statusName", projectStatusName); |
| | | result.put("name", projectVo.getName()); |
| | | |
| | | StringBuilder stringBuilderManager = new StringBuilder(); |
| | | |
| | | if (projectVo.getProjectManagerVos().size() > 0) { |
| | | stringBuilderManager.append(projectVo.getProjectManagerVos().get(0).getName()); |
| | | stringBuilderManager.append("("); |
| | | stringBuilderManager.append(projectVo.getProjectManagerVos().get(0).getAccount()); |
| | | stringBuilderManager.append(")"); |
| | | } |
| | | |
| | | result.put("manager", stringBuilderManager.toString()); |
| | | result.put("members", CommonUtil.convertUserVosToString(projectVo.getProjectUserVos())); |
| | | result.put("projectKey", projectVo.getProjectKey()); |
| | | result.put("period", projectVo.getStartDate() + " - " + projectVo.getEndDate()); |
| | | results.add(result); |
| | | } |
| | | |
| | | return results; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void findLastUseProject(Map<String, Object> resJsonData) { |
| | | UserVo loginUser = this.webAppUtil.getLoginUser(); |
| | | Project project = null; |
| | | |
| | | if (loginUser.getLastProjectId() != null) { |
| | | project = this.projectRepository.getOne(loginUser.getLastProjectId()); |
| | | } |
| | | |
| | | if (project == null) { |
| | | project = this.projectRepository.findByWorkspaceIdAndDefaultYn(loginUser.getLastWorkspaceId(), true); |
| | | } |
| | | |
| | | if (project == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.PROJECT_NOT_EXIST)); |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, ConvertUtil.copyProperties(project, ProjectVo.class)); |
| | | } |
| | | |
| | | } |
src/main/java/kr/wisestone/owl/service/impl/QnaServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/ReservationDisableUserServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/SeverityServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/SystemRoleServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/UserHistoryServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/UserInviteProjectServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/UserInviteServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/UserServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/UserWithDrawServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/UserWorkspaceServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/WidgetServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/WorkflowServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/WorkflowStatusServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/WorkflowTransitionServiceImpl.java
src/main/java/kr/wisestone/owl/service/impl/WorkspaceServiceImpl.java
src/main/java/kr/wisestone/owl/type/LikeType.java
src/main/java/kr/wisestone/owl/util/ApplicationContextUtil.java
src/main/java/kr/wisestone/owl/util/CommonUtil.java
src/main/java/kr/wisestone/owl/util/ConvertUtil.java
src/main/java/kr/wisestone/owl/util/DateUtil.java
src/main/java/kr/wisestone/owl/util/ElasticSearchUtil.java
src/main/java/kr/wisestone/owl/util/MapUtil.java
src/main/java/kr/wisestone/owl/util/PageUtil.java
src/main/java/kr/wisestone/owl/util/SecurityUtils.java
src/main/java/kr/wisestone/owl/util/StringTemplateUtil.java
src/main/java/kr/wisestone/owl/util/ThreadCounter.java
src/main/java/kr/wisestone/owl/util/WebAppUtil.java
src/main/java/kr/wisestone/owl/vo/AttachedFileVo.java
src/main/java/kr/wisestone/owl/vo/BaseVo.java
src/main/java/kr/wisestone/owl/vo/CustomFieldValueVo.java
src/main/java/kr/wisestone/owl/vo/CustomFieldVo.java
src/main/java/kr/wisestone/owl/vo/EventVo.java
src/main/java/kr/wisestone/owl/vo/ExportExcelAttrVo.java
src/main/java/kr/wisestone/owl/vo/ExportExcelVo.java
src/main/java/kr/wisestone/owl/vo/FaqVo.java
src/main/java/kr/wisestone/owl/vo/GuideVo.java
src/main/java/kr/wisestone/owl/vo/IssueCommentVo.java
src/main/java/kr/wisestone/owl/vo/IssueCustomFieldValueVo.java
src/main/java/kr/wisestone/owl/vo/IssueHistoryVo.java
src/main/java/kr/wisestone/owl/vo/IssueRelationVo.java
src/main/java/kr/wisestone/owl/vo/IssueReservationVo.java
src/main/java/kr/wisestone/owl/vo/IssueStatusVo.java
src/main/java/kr/wisestone/owl/vo/IssueTypeCustomFieldVo.java
src/main/java/kr/wisestone/owl/vo/IssueTypeVo.java
src/main/java/kr/wisestone/owl/vo/IssueVersionVo.java
src/main/java/kr/wisestone/owl/vo/IssueVo.java
src/main/java/kr/wisestone/owl/vo/ManageUserVo.java
src/main/java/kr/wisestone/owl/vo/MessageVo.java
src/main/java/kr/wisestone/owl/vo/NoticeVo.java
src/main/java/kr/wisestone/owl/vo/PageVo.java
src/main/java/kr/wisestone/owl/vo/PaymentHistoryVo.java
src/main/java/kr/wisestone/owl/vo/PaymentVo.java
src/main/java/kr/wisestone/owl/vo/PermissionVo.java
src/main/java/kr/wisestone/owl/vo/PriorityVo.java
src/main/java/kr/wisestone/owl/vo/ProjectVo.java
src/main/java/kr/wisestone/owl/vo/QnaVo.java
src/main/java/kr/wisestone/owl/vo/ResMessageVo.java
src/main/java/kr/wisestone/owl/vo/ResPage.java
src/main/java/kr/wisestone/owl/vo/SeverityVo.java
src/main/java/kr/wisestone/owl/vo/UserInviteVo.java
src/main/java/kr/wisestone/owl/vo/UserVo.java
src/main/java/kr/wisestone/owl/vo/UserWorkspaceVo.java
src/main/java/kr/wisestone/owl/vo/WorkflowStatusVo.java
src/main/java/kr/wisestone/owl/vo/WorkflowTransitionVo.java
src/main/java/kr/wisestone/owl/vo/WorkflowVo.java
src/main/java/kr/wisestone/owl/vo/WorkspaceVo.java
src/main/java/kr/wisestone/owl/web/condition/AttachedFileCondition.java
src/main/java/kr/wisestone/owl/web/condition/CustomFieldCondition.java
src/main/java/kr/wisestone/owl/web/condition/EventCondition.java
src/main/java/kr/wisestone/owl/web/condition/FaqCondition.java
src/main/java/kr/wisestone/owl/web/condition/GuideCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueHistoryCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueRelationCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueReservationCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueStatusCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueTypeCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueTypeCustomFieldCondition.java
src/main/java/kr/wisestone/owl/web/condition/IssueVersionCondition.java
src/main/java/kr/wisestone/owl/web/condition/NoticeCondition.java
src/main/java/kr/wisestone/owl/web/condition/ProjectCondition.java
src/main/java/kr/wisestone/owl/web/condition/QnaCondition.java
src/main/java/kr/wisestone/owl/web/condition/UserCondition.java
src/main/java/kr/wisestone/owl/web/condition/UserHistoryCondition.java
src/main/java/kr/wisestone/owl/web/condition/UserWorkspaceCondition.java
src/main/java/kr/wisestone/owl/web/condition/WidgetCondition.java
src/main/java/kr/wisestone/owl/web/condition/WorkflowCondition.java
src/main/java/kr/wisestone/owl/web/condition/WorkflowStatusCondition.java
src/main/java/kr/wisestone/owl/web/controller/AttatchedFileController.java
src/main/java/kr/wisestone/owl/web/controller/BaseController.java
src/main/java/kr/wisestone/owl/web/controller/CustomFieldController.java
src/main/java/kr/wisestone/owl/web/controller/EventController.java
src/main/java/kr/wisestone/owl/web/controller/FaqController.java
src/main/java/kr/wisestone/owl/web/controller/GanttController.java
src/main/java/kr/wisestone/owl/web/controller/GuideController.java
src/main/java/kr/wisestone/owl/web/controller/IssueCommentController.java
src/main/java/kr/wisestone/owl/web/controller/IssueController.java
src/main/java/kr/wisestone/owl/web/controller/IssueHistoryController.java
src/main/java/kr/wisestone/owl/web/controller/IssueRelationController.java
src/main/java/kr/wisestone/owl/web/controller/IssueReservationController.java
src/main/java/kr/wisestone/owl/web/controller/IssueSearchController.java
src/main/java/kr/wisestone/owl/web/controller/IssueStatusController.java
src/main/java/kr/wisestone/owl/web/controller/IssueTableConfigController.java
src/main/java/kr/wisestone/owl/web/controller/IssueTypeController.java
src/main/java/kr/wisestone/owl/web/controller/IssueTypeCustomFieldController.java
src/main/java/kr/wisestone/owl/web/controller/IssueUserController.java
src/main/java/kr/wisestone/owl/web/controller/IssueVersionController.java
src/main/java/kr/wisestone/owl/web/controller/LanguageController.java
src/main/java/kr/wisestone/owl/web/controller/ManageUserController.java
src/main/java/kr/wisestone/owl/web/controller/NoticeController.java
src/main/java/kr/wisestone/owl/web/controller/PaymentController.java
src/main/java/kr/wisestone/owl/web/controller/PermissionController.java
src/main/java/kr/wisestone/owl/web/controller/PriorityController.java
src/main/java/kr/wisestone/owl/web/controller/ProjectController.java
src/main/java/kr/wisestone/owl/web/controller/QnaController.java
src/main/java/kr/wisestone/owl/web/controller/ReservationDisableUserController.java
src/main/java/kr/wisestone/owl/web/controller/SeverityController.java
src/main/java/kr/wisestone/owl/web/controller/SystemEmailController.java
src/main/java/kr/wisestone/owl/web/controller/UserController.java
src/main/java/kr/wisestone/owl/web/controller/UserHistoryController.java
src/main/java/kr/wisestone/owl/web/controller/UserInviteController.java
src/main/java/kr/wisestone/owl/web/controller/UserWorkspaceController.java
src/main/java/kr/wisestone/owl/web/controller/WebSocketSessionController.java
src/main/java/kr/wisestone/owl/web/controller/WidgetController.java
src/main/java/kr/wisestone/owl/web/controller/WorkflowController.java
src/main/java/kr/wisestone/owl/web/controller/WorkflowStatusController.java
src/main/java/kr/wisestone/owl/web/controller/WorkspaceController.java
src/main/java/kr/wisestone/owl/web/converter/FileHttpMessageConverter.java
src/main/java/kr/wisestone/owl/web/form/CustomFieldForm.java
src/main/java/kr/wisestone/owl/web/form/EventForm.java
src/main/java/kr/wisestone/owl/web/form/FaqForm.java
src/main/java/kr/wisestone/owl/web/form/GuideForm.java
src/main/java/kr/wisestone/owl/web/form/IssueCommentForm.java
src/main/java/kr/wisestone/owl/web/form/IssueForm.java
src/main/java/kr/wisestone/owl/web/form/IssueReservationForm.java
src/main/java/kr/wisestone/owl/web/form/IssueStatusChangeForm.java
src/main/java/kr/wisestone/owl/web/form/IssueStatusForm.java
src/main/java/kr/wisestone/owl/web/form/IssueTypeCustomFieldForm.java
src/main/java/kr/wisestone/owl/web/form/IssueTypeForm.java
src/main/java/kr/wisestone/owl/web/form/ManageUserForm.java
src/main/java/kr/wisestone/owl/web/form/NoticeForm.java
src/main/java/kr/wisestone/owl/web/form/PaymentForm.java
src/main/java/kr/wisestone/owl/web/form/ProjectForm.java
src/main/java/kr/wisestone/owl/web/form/QnaForm.java
src/main/java/kr/wisestone/owl/web/form/UserForm.java
src/main/java/kr/wisestone/owl/web/form/UserInviteForm.java
src/main/java/kr/wisestone/owl/web/form/UserWorkspaceForm.java
src/main/java/kr/wisestone/owl/web/form/WorkflowForm.java
src/main/java/kr/wisestone/owl/web/form/WorkflowStatusForm.java
src/main/java/kr/wisestone/owl/web/form/WorkspaceForm.java
src/main/java/kr/wisestone/owl/web/resolver/OwlResponseEntityExceptionHandler.java
src/main/java/kr/wisestone/owl/web/view/AbstractExcelView.java
src/main/java/kr/wisestone/owl/web/view/ExcelView.java
src/main/java/kr/wisestone/owl/web/view/FileDownloadView.java
src/main/resources/META-INF/orm.xml
src/main/resources/log4j2.xml
src/main/resources/mails/issueAddEmail.html
src/main/resources/mails/issueRemoveEmail.html
src/main/resources/mails/issueSendEmail.html
src/main/resources/mails/projectDefaultExcludeAndManagerIncludeEmail.html
src/main/resources/mails/projectDefaultExcludeEmail.html
src/main/resources/mails/projectDefaultIncludeEmail.html
src/main/resources/mails/projectManagerExcludeAndDefaultIncludeEmail.html
src/main/resources/mails/projectManagerExcludeEmail.html
src/main/resources/mails/projectManagerIncludeEmail.html
src/main/resources/mails/regularPaymentCancelByAccountingManagerEmail.html
src/main/resources/mails/regularPaymentCancelEmail.html
src/main/resources/mails/regularPaymentEmail.html
src/main/resources/mails/regularPaymentModifyEmail.html
src/main/resources/mails/totalStatisticsEmail.html
src/main/resources/mails/userJoinStatisticsEmail.html
src/main/resources/mails/userSearchPasswordEmail.html
src/main/resources/mails/userWithDrawEmail.html
src/main/resources/mails/workspaceExpireAlarmEmail.html
src/main/resources/mails/workspaceExpireEmail.html
src/main/resources/mails/workspaceInviteNewUserEmail.html
src/main/resources/mails/workspaceInviteSystemUserEmail.html
src/main/resources/mails/workspaceJoinEmail.html
src/main/resources/mails/workspaceMaxStorageExcessEmail.html
src/main/resources/mails/workspaceMaxUserExcessEmail.html
src/main/resources/migration/V1_1__Initial_Setup.sql
src/main/resources/migration/V1_2__Alter_Table.sql
src/main/resources/migration/V1_3__Alter_Table.sql
src/main/resources/migration/V1_4__Alter_Table.sql
src/main/resources/migration/V1_5__Alter_Table.sql
src/main/resources/migration/V1_6__Alter_Table.sql
src/main/resources/migration/V1_7__Alter_Table.sql
src/main/resources/migration/V1_8__Alter_Table.sql
src/main/resources/migration/V1_9__Alter_Table.sql
src/main/resources/mybatis/config/mybatis-config.xml
src/main/resources/mybatis/query-template/attachedFile-template.xml
src/main/resources/mybatis/query-template/customField-template.xml
src/main/resources/mybatis/query-template/event-template.xml
src/main/resources/mybatis/query-template/faq-template.xml
src/main/resources/mybatis/query-template/guide-template.xml
src/main/resources/mybatis/query-template/issue-template.xml
src/main/resources/mybatis/query-template/issueCustomFieldValue-template.xml
src/main/resources/mybatis/query-template/issueHistory-template.xml
src/main/resources/mybatis/query-template/issueStatus-template.xml
src/main/resources/mybatis/query-template/issueType-template.xml
src/main/resources/mybatis/query-template/issueUser-template.xml
src/main/resources/mybatis/query-template/notice-template.xml
src/main/resources/mybatis/query-template/project-template.xml
src/main/resources/mybatis/query-template/projectRoleUser-template.xml
src/main/resources/mybatis/query-template/qna-template.xml
src/main/resources/mybatis/query-template/user-template.xml
src/main/resources/mybatis/query-template/userWorkspace-template.xml
src/main/resources/mybatis/query-template/widget-template.xml
src/main/resources/mybatis/query-template/workflow-template.xml
src/main/resources/mybatis/query-template/workspace-template.xml
src/main/resources/system_design.properties
src/main/resources/system_dev.properties
src/main/resources/system_prod.properties
src/main/resources/system_test.properties |