블로그 포스팅자동화진행중
This commit is contained in:
parent
2d8955144b
commit
d3bd8fe3ec
@ -1,19 +1,15 @@
|
|||||||
package com.itn.admin.cmn.config;
|
package com.itn.admin.cmn.config;
|
||||||
|
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||||
import org.mybatis.spring.SqlSessionTemplate;
|
import org.mybatis.spring.SqlSessionTemplate;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@ -24,6 +20,7 @@ import javax.sql.DataSource;
|
|||||||
,"com.itn.admin.itn.mjon.spam.mapper"
|
,"com.itn.admin.itn.mjon.spam.mapper"
|
||||||
,"com.itn.admin.itn.user.mapper"
|
,"com.itn.admin.itn.user.mapper"
|
||||||
,"com.itn.admin.itn.code.mapper"
|
,"com.itn.admin.itn.code.mapper"
|
||||||
|
,"com.itn.admin.itn.blog.mapper"
|
||||||
}
|
}
|
||||||
, sqlSessionFactoryRef = "factory")
|
, sqlSessionFactoryRef = "factory")
|
||||||
class MainDatabaseConfig {
|
class MainDatabaseConfig {
|
||||||
@ -47,7 +44,8 @@ class MainDatabaseConfig {
|
|||||||
|
|
||||||
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
|
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
|
||||||
sqlSessionFactory.setDataSource(dataSource);
|
sqlSessionFactory.setDataSource(dataSource);
|
||||||
sqlSessionFactory.setTypeAliasesPackage("com.itn.admin.itn.*");
|
// sqlSessionFactory.setTypeAliasesPackage("com.itn.admin.itn.*");
|
||||||
|
// sqlSessionFactory.setTypeAliasesPackage("com.itn.admin.itn");
|
||||||
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/itn/**/*Mapper.xml"));
|
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/itn/**/*Mapper.xml"));
|
||||||
sqlSessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml"));
|
sqlSessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml"));
|
||||||
return sqlSessionFactory.getObject();
|
return sqlSessionFactory.getObject();
|
||||||
|
|||||||
@ -28,6 +28,7 @@ public class UserInterceptor implements HandlerInterceptor {
|
|||||||
log.info(" :: Request URL: " + request.getRequestURL());
|
log.info(" :: Request URL: " + request.getRequestURL());
|
||||||
log.info(" :: Request Method: " + request.getMethod());
|
log.info(" :: Request Method: " + request.getMethod());
|
||||||
log.info(" :: Remote Address: " + request.getRemoteAddr());
|
log.info(" :: Remote Address: " + request.getRemoteAddr());
|
||||||
|
|
||||||
log.info(" :: modelAndView: " + modelAndView);
|
log.info(" :: modelAndView: " + modelAndView);
|
||||||
|
|
||||||
if (modelAndView != null) {
|
if (modelAndView != null) {
|
||||||
|
|||||||
@ -1,14 +1,20 @@
|
|||||||
package com.itn.admin.cmn.util.slack;
|
package com.itn.admin.cmn.util.slack;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 레거시 Slack 유틸리티 클래스
|
||||||
|
*
|
||||||
|
* @deprecated 새로운 프로젝트에서는 {@link SlackNotificationService}를 사용하세요.
|
||||||
|
* 기존 코드 호환성을 위해 유지됩니다.
|
||||||
|
*
|
||||||
* packageName : com.itn.mjonApi.util.slack
|
* packageName : com.itn.mjonApi.util.slack
|
||||||
* fileName : Slack
|
* fileName : Slack
|
||||||
* author : hylee
|
* author : hylee
|
||||||
@ -18,40 +24,74 @@ import java.io.IOException;
|
|||||||
* DATE AUTHOR NOTE
|
* DATE AUTHOR NOTE
|
||||||
* -----------------------------------------------------------
|
* -----------------------------------------------------------
|
||||||
* 2023-08-28 hylee 최초 생성
|
* 2023-08-28 hylee 최초 생성
|
||||||
|
* 2025-01-16 claude SlackNotificationService 통합을 위한 리팩토링
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@Deprecated
|
||||||
public class SlackUtil {
|
public class SlackUtil {
|
||||||
public static void sendMorakMenuToSlack(String sendMsg) {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모락 메뉴 알림 발송 (레거시 메서드)
|
||||||
|
* @deprecated 새로운 알림은 {@link SlackNotificationService#sendCustomMessage}를 사용하세요.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static void sendMorakMenuToSlack(String sendMsg) {
|
||||||
String url = "https://hooks.slack.com/services/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";
|
String url = "https://hooks.slack.com/services/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";
|
||||||
|
sendSlackMessage(url, "모락메뉴api", sendMsg, "모락 메뉴", ":bento:");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 범용 슬랙 메시지 발송 메서드
|
||||||
|
* @param webhookUrl 웹훅 URL
|
||||||
|
* @param channel 채널명
|
||||||
|
* @param message 메시지 내용
|
||||||
|
* @param username 발송자명
|
||||||
|
* @param iconEmoji 아이콘 이모지
|
||||||
|
*/
|
||||||
|
public static void sendSlackMessage(String webhookUrl, String channel, String message,
|
||||||
|
String username, String iconEmoji) {
|
||||||
HttpClient client = new HttpClient();
|
HttpClient client = new HttpClient();
|
||||||
PostMethod post = new PostMethod(url);
|
PostMethod post = new PostMethod(webhookUrl);
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String munjaText = sendMsg;
|
json.put("channel", channel);
|
||||||
json.put("channel", "모락메뉴api");
|
json.put("text", message);
|
||||||
|
json.put("username", username);
|
||||||
json.put("text", munjaText);
|
if (iconEmoji != null && !iconEmoji.trim().isEmpty()) {
|
||||||
// json.put("icon_emoji", ":원하는 아이콘:"); //커스터마이징으로 아이콘 만들수도 있다!
|
json.put("icon_emoji", iconEmoji);
|
||||||
json.put("username", "모락 메뉴");
|
}
|
||||||
|
|
||||||
|
|
||||||
post.addParameter("payload", json.toString());
|
post.addParameter("payload", json.toString());
|
||||||
// 처음에 utf-8로 content-type안넣어주니까 한글은 깨져서 content-type넣어줌
|
|
||||||
post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
|
||||||
int responseCode = client.executeMethod(post);
|
int responseCode = client.executeMethod(post);
|
||||||
String response = post.getResponseBodyAsString();
|
String response = post.getResponseBodyAsString();
|
||||||
if (responseCode != HttpStatus.SC_OK) {
|
|
||||||
System.out.println("Response: " + response);
|
if (responseCode == HttpStatus.SC_OK) {
|
||||||
|
log.debug("Slack 메시지 발송 성공: {} to {}", message, channel);
|
||||||
|
} else {
|
||||||
|
log.warn("Slack 메시지 발송 실패 - Code: {}, Response: {}", responseCode, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
System.out.println("IllegalArgumentException posting to Slack " + e);
|
log.error("Slack 발송 중 잘못된 인자 오류: {}", e.getMessage(), e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("IOException posting to Slack " + e);
|
log.error("Slack 발송 중 IO 오류: {}", e.getMessage(), e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Slack 발송 중 예상치 못한 오류: {}", e.getMessage(), e);
|
||||||
} finally {
|
} finally {
|
||||||
post.releaseConnection();
|
post.releaseConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 단순 메시지 발송 (기본 설정 사용)
|
||||||
|
* @param webhookUrl 웹훅 URL
|
||||||
|
* @param message 메시지 내용
|
||||||
|
*/
|
||||||
|
public static void sendSimpleMessage(String webhookUrl, String message) {
|
||||||
|
sendSlackMessage(webhookUrl, "general", message, "ITN-Admin", ":robot_face:");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package com.itn.admin.cmn.vo;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@SuperBuilder
|
@SuperBuilder
|
||||||
@ -19,10 +21,14 @@ public class CmnVO {
|
|||||||
private int totalPageCount; // 총 페이지 수
|
private int totalPageCount; // 총 페이지 수
|
||||||
private int startPage; // 페이지네이션의 시작 페이지 번호
|
private int startPage; // 페이지네이션의 시작 페이지 번호
|
||||||
private int endPage; // 페이지네이션의 끝 페이지 번호
|
private int endPage; // 페이지네이션의 끝 페이지 번호
|
||||||
private String frstRegisterId;
|
private String createdBy;
|
||||||
private String frstRegistPnttm;
|
private LocalDateTime frstRegistPnttm;
|
||||||
private String lastUpdusrId;
|
private String updatedBy;
|
||||||
private String lastUpdtPnttm;
|
private LocalDateTime lastUpdtPnttm;
|
||||||
|
|
||||||
|
// 등록자/수정자 정보
|
||||||
|
private String frstRegisterId; // 최초 등록자 ID
|
||||||
|
private String lastUpdusrId; // 최종 수정자 ID
|
||||||
|
|
||||||
|
|
||||||
// 페이징을 위한 offset과 limit을 계산하는 메서드
|
// 페이징을 위한 offset과 limit을 계산하는 메서드
|
||||||
|
|||||||
@ -213,7 +213,7 @@ public class CommuteServiceImpl implements CommuteService {
|
|||||||
|
|
||||||
// 활동 시간이 기준 시간보다 이전이면 조기 퇴근
|
// 활동 시간이 기준 시간보다 이전이면 조기 퇴근
|
||||||
if (activityTime.isBefore(checkTime)) {
|
if (activityTime.isBefore(checkTime)) {
|
||||||
return "70"; //""조기퇴근";
|
return "90"; //""조기퇴근";
|
||||||
}
|
}
|
||||||
// 그렇지 않으면 빈 문자열 반환
|
// 그렇지 않으면 빈 문자열 반환
|
||||||
return "";
|
return "";
|
||||||
@ -228,7 +228,7 @@ public class CommuteServiceImpl implements CommuteService {
|
|||||||
|
|
||||||
// 활동 시간이 기준 시간보다 이후면 지각
|
// 활동 시간이 기준 시간보다 이후면 지각
|
||||||
if (activityTime.isAfter(checkTime)) {
|
if (activityTime.isAfter(checkTime)) {
|
||||||
return "60"; // 지각 시 60 반환 (공통코드 COMMUTE)
|
return "70"; // 지각 시 70 반환 (공통코드 COMMUTE)
|
||||||
}
|
}
|
||||||
// 그렇지 않으면 빈 문자열 반환
|
// 그렇지 않으면 빈 문자열 반환
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.itn.admin.itn.blog.service;
|
||||||
|
|
||||||
|
import com.itn.admin.itn.blog.mapper.domain.BlogAccountWithSourcesDTO;
|
||||||
|
import com.itn.admin.itn.blog.mapper.domain.BlogPostHistoryVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface BlogPosingService {
|
||||||
|
BlogAccountWithSourcesDTO getAccountWithSources(Long blogId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 워크플로우 히스토리 조회 (페이징 지원)
|
||||||
|
*/
|
||||||
|
List<BlogPostHistoryVO> getWorkflowHistory(String blogId, String urlId, String status, int limit, int offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 워크플로우 통계 조회
|
||||||
|
*/
|
||||||
|
Map<String, Object> getWorkflowStatistics(Long blogId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 실시간 진행상황 조회
|
||||||
|
*/
|
||||||
|
BlogPostHistoryVO getPublishProgress(Long postId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 실패 원인별 분석
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> getFailureAnalysis(Long blogId, int days);
|
||||||
|
}
|
||||||
@ -180,7 +180,7 @@ public class UserServiceImpl implements UserService {
|
|||||||
return RestResponse.builder()
|
return RestResponse.builder()
|
||||||
.status(HttpStatus.BAD_REQUEST) // 실패
|
.status(HttpStatus.BAD_REQUEST) // 실패
|
||||||
.data(userVO.getUserName())
|
.data(userVO.getUserName())
|
||||||
.msg("실패하였습니다.")
|
.msg("그룹웨어에 해당 이름으로 여러개 아이디가 등록되었습니다.\n확인해주세요")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
userVO.setGwId(gwUserId);
|
userVO.setGwId(gwUserId);
|
||||||
|
|||||||
@ -1,2 +1,25 @@
|
|||||||
agent.file.dir.path=X:\agent_file
|
agent.file.dir.path=X:\agent_file
|
||||||
spring.thymeleaf.cache=false
|
spring.thymeleaf.cache=false
|
||||||
|
|
||||||
|
# Tomcat 세션 영속화 비활성화 (개발 환경)
|
||||||
|
server.servlet.session.persistent=false
|
||||||
|
|
||||||
|
# 블로그 발행 설정
|
||||||
|
blog.generate.url=http://192.168.0.78:5000/blog/generate
|
||||||
|
blog.generate.timeout-ms=60000
|
||||||
|
|
||||||
|
# Python ?? ??
|
||||||
|
python.base-url=http://192.168.0.78:5000
|
||||||
|
python.path=/blog/generate
|
||||||
|
python.timeout-ms=20000
|
||||||
|
|
||||||
|
# Slack Notification Settings
|
||||||
|
slack.notification.enabled=true
|
||||||
|
slack.webhook.default=https://hooks.slack.com/services/YOUR_WEBHOOK_URL_HERE
|
||||||
|
slack.webhook.blog-schedule=https://hooks.slack.com/services/YOUR_BLOG_SCHEDULE_WEBHOOK_URL
|
||||||
|
slack.webhook.system-alert=https://hooks.slack.com/services/YOUR_SYSTEM_ALERT_WEBHOOK_URL
|
||||||
|
slack.channel.default=general
|
||||||
|
slack.channel.blog-schedule=blog-alerts
|
||||||
|
slack.channel.system-alert=system-alerts
|
||||||
|
slack.username=ITN-Admin
|
||||||
|
slack.icon.emoji=:robot_face:
|
||||||
@ -1,2 +1,19 @@
|
|||||||
agent.file.dir.path=/home/docker/tomcat_8081_to_8089_2022_0712/kcc_adr_volume/agent_file
|
agent.file.dir.path=/home/docker/tomcat_8081_to_8089_2022_0712/kcc_adr_volume/agent_file
|
||||||
spring.thymeleaf.cache=true
|
spring.thymeleaf.cache=true
|
||||||
|
|
||||||
|
|
||||||
|
# Python ?? ??
|
||||||
|
python.base-url=http://192.168.0.78:5000
|
||||||
|
python.path=/blog/generate
|
||||||
|
python.timeout-ms=20000
|
||||||
|
|
||||||
|
# Slack Notification Settings
|
||||||
|
slack.notification.enabled=true
|
||||||
|
slack.webhook.default=https://hooks.slack.com/services/YOUR_PRODUCTION_WEBHOOK_URL_HERE
|
||||||
|
slack.webhook.blog-schedule=https://hooks.slack.com/services/YOUR_PROD_BLOG_SCHEDULE_WEBHOOK_URL
|
||||||
|
slack.webhook.system-alert=https://hooks.slack.com/services/YOUR_PROD_SYSTEM_ALERT_WEBHOOK_URL
|
||||||
|
slack.channel.default=general
|
||||||
|
slack.channel.blog-schedule=blog-alerts
|
||||||
|
slack.channel.system-alert=system-alerts
|
||||||
|
slack.username=ITN-Admin-PROD
|
||||||
|
slack.icon.emoji=:warning:
|
||||||
1
src/main/resources/docs/munjaon_tstory_state.json
Normal file
1
src/main/resources/docs/munjaon_tstory_state.json
Normal file
File diff suppressed because one or more lines are too long
@ -49,6 +49,7 @@
|
|||||||
USER_ID
|
USER_ID
|
||||||
FROM INTRAWARE.USR_GLOBAL
|
FROM INTRAWARE.USR_GLOBAL
|
||||||
WHERE NAME = #{userName}
|
WHERE NAME = #{userName}
|
||||||
|
AND STATUS = 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -30,23 +30,18 @@
|
|||||||
<typeAlias type="com.itn.admin.itn.bizTrip.mapper.domain.BizTripApprovalVO" alias="bizTripApprovalVO"/>
|
<typeAlias type="com.itn.admin.itn.bizTrip.mapper.domain.BizTripApprovalVO" alias="bizTripApprovalVO"/>
|
||||||
|
|
||||||
<typeAlias type="com.itn.admin.gw.holiday.mapper.domain.HolidayVO" alias="holidayVO"/>
|
<typeAlias type="com.itn.admin.gw.holiday.mapper.domain.HolidayVO" alias="holidayVO"/>
|
||||||
|
|
||||||
|
<!-- 블로그 예약 발행 관련 VO -->
|
||||||
|
<typeAlias type="com.itn.admin.itn.blog.mapper.domain.BlogScheduleVO" alias="blogScheduleVO"/>
|
||||||
|
<typeAlias type="com.itn.admin.itn.blog.mapper.domain.BlogScheduleExecutionVO" alias="blogScheduleExecutionVO"/>
|
||||||
|
<typeAlias type="com.itn.admin.itn.blog.mapper.domain.ScheduleCreateRequestDTO" alias="scheduleCreateRequestDTO"/>
|
||||||
|
<typeAlias type="com.itn.admin.itn.blog.mapper.domain.ScheduleUpdateRequestDTO" alias="scheduleUpdateRequestDTO"/>
|
||||||
|
<typeAlias type="com.itn.admin.itn.blog.mapper.domain.ScheduleSearchDTO" alias="scheduleSearchDTO"/>
|
||||||
|
<typeAlias type="com.itn.admin.itn.blog.mapper.domain.ScheduleStatisticsDTO" alias="scheduleStatisticsDTO"/>
|
||||||
|
|
||||||
|
<!-- 블로그 쿠키 매핑 관련 VO -->
|
||||||
|
<typeAlias type="com.itn.admin.itn.blog.mapper.domain.BlogCookieMappingVO" alias="blogCookieMappingVO"/>
|
||||||
|
|
||||||
</typeAliases>
|
</typeAliases>
|
||||||
|
|
||||||
<!-- <environments default="development">-->
|
|
||||||
<!-- <environment id="development">-->
|
|
||||||
<!-- <transactionManager type="JDBC">-->
|
|
||||||
<!-- <property name="..." value="..."/>-->
|
|
||||||
<!-- </transactionManager>-->
|
|
||||||
<!-- <dataSource type="POOLED">-->
|
|
||||||
<!-- <property name="driver" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>-->
|
|
||||||
<!-- <property name="url" value="jdbc:log4jdbc:mysql://192.168.0.30:3306/mjonUr_agent?serverTimezone=Asia/Seoul"/>-->
|
|
||||||
<!-- <property name="username" value="mjonAgentUr"/>-->
|
|
||||||
<!-- <property name="password" value="mjonAgentUr!@#$"/>-->
|
|
||||||
<!-- </dataSource>-->
|
|
||||||
<!-- </environment>-->
|
|
||||||
<!-- </environments>-->
|
|
||||||
<!-- <mappers>-->
|
|
||||||
<!-- <mapper resource="mapper/agent/AgentCThreeMapper.xml"/>-->
|
|
||||||
<!-- </mappers>-->
|
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -98,18 +98,6 @@
|
|||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- DataTables & Plugins -->
|
<!-- DataTables & Plugins -->
|
||||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
|||||||
@ -170,18 +170,6 @@
|
|||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- DataTables & Plugins -->
|
<!-- DataTables & Plugins -->
|
||||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,12 @@
|
|||||||
<link rel="stylesheet" th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
<link rel="stylesheet" th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||||
<link rel="stylesheet" th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
<link rel="stylesheet" th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||||
<link rel="stylesheet" th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
<link rel="stylesheet" th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||||
|
|
||||||
|
|
||||||
<!-- SweetAlert2 CSS -->
|
<!-- SweetAlert2 CSS -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<link rel="stylesheet" th:href="@{https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css}" >
|
<link rel="stylesheet" th:href="@{https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css}" >
|
||||||
|
|
||||||
|
|
||||||
@ -91,6 +96,20 @@
|
|||||||
<!-- SweetAlert2 JS -->
|
<!-- SweetAlert2 JS -->
|
||||||
<script th:src="@{https://cdn.jsdelivr.net/npm/sweetalert2@11}"></script>
|
<script th:src="@{https://cdn.jsdelivr.net/npm/sweetalert2@11}"></script>
|
||||||
|
|
||||||
|
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/* 메뉴 하이라이팅 */
|
/* 메뉴 하이라이팅 */
|
||||||
|
|||||||
@ -153,6 +153,41 @@
|
|||||||
<p>단어사전</p>
|
<p>단어사전</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link" >
|
||||||
|
<i class="nav-icon fas fa-blog"></i>
|
||||||
|
<p>
|
||||||
|
블로그 자동 포스팅
|
||||||
|
<i class="right fas fa-angle-left"></i>
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
<ul class="nav nav-treeview">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a th:href="@{/blog/accounts/list}" class="nav-link">
|
||||||
|
<i class="fas fa-users-cog nav-icon"></i>
|
||||||
|
<p>Blog 계정 관리</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a th:href="@{/blog/sources/list}" class="nav-link">
|
||||||
|
<i class="fas fa-file-alt nav-icon"></i>
|
||||||
|
<p>포스팅 소스 관리</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a th:href="@{/blog/posing/list}" class="nav-link">
|
||||||
|
<i class="fas fa-paper-plane nav-icon"></i>
|
||||||
|
<p>블로그 포스팅 실행</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a th:href="@{/blog/history/list}" class="nav-link">
|
||||||
|
<i class="fas fa-history nav-icon"></i>
|
||||||
|
<p>포스팅 이력 조회</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<!-- <li class="nav-item">
|
<!-- <li class="nav-item">
|
||||||
<a href="#" class="nav-link" >
|
<a href="#" class="nav-link" >
|
||||||
<i class="nav-icon fas fa-sms"></i>
|
<i class="nav-icon fas fa-sms"></i>
|
||||||
|
|||||||
@ -154,18 +154,6 @@
|
|||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- DataTables & Plugins -->
|
<!-- DataTables & Plugins -->
|
||||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
const commonExportOptions = {
|
const commonExportOptions = {
|
||||||
|
|||||||
@ -44,13 +44,13 @@
|
|||||||
<table id="blogAccountTable" class="table table-bordered table-hover">
|
<table id="blogAccountTable" class="table table-bordered table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>블로그 ID</th>
|
<th></th>
|
||||||
<th>플랫폼</th>
|
<!-- <th>블로그 ID</th>-->
|
||||||
<th>블로그 이름</th>
|
<th>블로그 이름</th>
|
||||||
<th>블로그 URL</th>
|
<th>블로그 URL</th>
|
||||||
|
<th>포스팅 통계</th>
|
||||||
<th>등록일</th>
|
<th>등록일</th>
|
||||||
<th>수정일</th>
|
<th>수정일</th>
|
||||||
<th>액션</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -85,30 +85,53 @@
|
|||||||
"autoWidth": false,
|
"autoWidth": false,
|
||||||
"responsive": true,
|
"responsive": true,
|
||||||
"ajax": {
|
"ajax": {
|
||||||
"url": "/api/blog/accounts/active", // 활성 블로그 계정 목록 API
|
"url": "/api/blog/posing/list",
|
||||||
"dataSrc": ""
|
"dataSrc": "data"
|
||||||
},
|
},
|
||||||
"columns": [
|
"columns": [
|
||||||
{"data": "blog_id"},
|
|
||||||
{"data": "platform"},
|
|
||||||
{"data": "blog_name"},
|
|
||||||
{"data": "blog_url"},
|
|
||||||
{
|
|
||||||
"data": "reg_date",
|
|
||||||
"render": function (data, type, row) {
|
|
||||||
return moment(data).format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data": "mod_date",
|
|
||||||
"render": function (data, type, row) {
|
|
||||||
return moment(data).format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"data": null,
|
"data": null,
|
||||||
"render": function (data, type, row) {
|
"render": function (data, type, row) {
|
||||||
return '<button class="btn btn-info btn-sm manage-button" data-id="' + row.blog_id + '">관리</button>';
|
return '<button class="btn btn-info btn-sm manage-button" data-id="' + row.blogId + '">선택</button>';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// {"data": "blogId"},
|
||||||
|
{"data": "blogName"},
|
||||||
|
{"data": "blogUrl"},
|
||||||
|
{
|
||||||
|
"data": null,
|
||||||
|
"render": function (data, type, row) {
|
||||||
|
const postCount = row.totalPostCount || 0;
|
||||||
|
const lastPublished = row.lastPublishedAt ?
|
||||||
|
moment(row.lastPublishedAt).format('YYYY-MM-DD HH:mm') : '-';
|
||||||
|
|
||||||
|
// 발행 횟수에 따른 배지 색상 결정
|
||||||
|
let countBadgeClass = 'badge-secondary';
|
||||||
|
if (postCount > 50) countBadgeClass = 'badge-success';
|
||||||
|
else if (postCount > 20) countBadgeClass = 'badge-info';
|
||||||
|
else if (postCount > 0) countBadgeClass = 'badge-primary';
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="text-center">
|
||||||
|
<span class="badge ${countBadgeClass} mb-1">${postCount}개 포스팅</span>
|
||||||
|
<br>
|
||||||
|
<small class="text-muted">
|
||||||
|
<i class="far fa-clock"></i> ${lastPublished}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": "frstRegistPnttm",
|
||||||
|
"render": function (data, type, row) {
|
||||||
|
return moment(data).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": "lastUpdtPnttm",
|
||||||
|
"render": function (data, type, row) {
|
||||||
|
return moment(data).format('YYYY-MM-DD HH:mm:ss');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -117,11 +140,11 @@
|
|||||||
// 행 클릭 이벤트 (또는 관리 버튼 클릭 이벤트)
|
// 행 클릭 이벤트 (또는 관리 버튼 클릭 이벤트)
|
||||||
$('#blogAccountTable tbody').on('click', '.manage-button', function () {
|
$('#blogAccountTable tbody').on('click', '.manage-button', function () {
|
||||||
const blogId = $(this).data('id');
|
const blogId = $(this).data('id');
|
||||||
location.href = '/blog/posting/manage/' + blogId; // 두 번째 페이지로 이동
|
location.href = '/blog/posing/manage/' + blogId; // 두 번째 페이지로 이동
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>g
|
||||||
@ -148,18 +148,6 @@
|
|||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- DataTables & Plugins -->
|
<!-- DataTables & Plugins -->
|
||||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
|||||||
@ -345,18 +345,6 @@
|
|||||||
<!-- ./wrapper -->
|
<!-- ./wrapper -->
|
||||||
|
|
||||||
<!-- DataTables & Plugins -->
|
<!-- DataTables & Plugins -->
|
||||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
|
||||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
const commonExportOptions = {
|
const commonExportOptions = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user