inkoreakim 2 лет назад
Родитель
Сommit
a675393003
28 измененных файлов с 355 добавлено и 206 удалено
  1. 2 1
      build.gradle
  2. 1 1
      src/main/generated/com/example/ili_web/member/domain/QMember.java
  3. 5 0
      src/main/java/com/example/ili_web/board/controller/BoardController.java
  4. 3 0
      src/main/java/com/example/ili_web/board/repository/BoardRepository.java
  5. 7 0
      src/main/java/com/example/ili_web/board/service/BoardService.java
  6. 11 3
      src/main/java/com/example/ili_web/config/MvcConfig.java
  7. 50 0
      src/main/java/com/example/ili_web/config/SecurityConfig.java
  8. 1 0
      src/main/java/com/example/ili_web/main/controller/MainController.java
  9. 2 2
      src/main/java/com/example/ili_web/member/controller/MemberController.java
  10. 46 2
      src/main/java/com/example/ili_web/member/domain/Member.java
  11. 4 0
      src/main/java/com/example/ili_web/security/CustomAuthFilter.java
  12. 30 0
      src/main/java/com/example/ili_web/security/LoginProvider.java
  13. 58 0
      src/main/java/com/example/ili_web/security/MemberDetailService.java
  14. 25 0
      src/main/java/com/example/ili_web/security/UserDetailsServiceImpl.java
  15. 1 1
      src/main/resources/application.properties
  16. 5 0
      src/main/resources/static/css/backoffice.css
  17. 11 0
      src/main/resources/static/css/index.css
  18. BIN
      src/main/resources/static/image/banner-airplane.jpg
  19. BIN
      src/main/resources/static/image/banner-container.jpg
  20. BIN
      src/main/resources/static/image/banner-intro.jpg
  21. BIN
      src/main/resources/static/image/banner-ships.jpg
  22. 46 0
      src/main/resources/static/js/admin/adminChart.js
  23. 3 9
      src/main/resources/static/js/admin/login.js
  24. 1 5
      src/main/resources/templates/html/about.html
  25. 4 3
      src/main/resources/templates/html/admin/backoffice.html
  26. 3 3
      src/main/resources/templates/html/admin/login.html
  27. 0 5
      src/main/resources/templates/html/business-sector.html
  28. 36 171
      src/main/resources/templates/html/index.html

+ 2 - 1
build.gradle

@@ -25,7 +25,8 @@ repositories {
 
 dependencies {
     implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
-    implementation 'org.springframework.security:spring-security-crypto:5.7.1'
+    implementation 'org.springframework.boot:spring-boot-starter-security'
+    implementation 'org.springframework.security:spring-security-crypto:6.2.1'
     implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
     implementation 'org.springframework.boot:spring-boot-starter-graphql'
     implementation 'org.springframework.boot:spring-boot-starter-web'

+ 1 - 1
src/main/generated/com/example/ili_web/member/domain/QMember.java

@@ -31,7 +31,7 @@ public class QMember extends EntityPathBase<Member> {
 
     public final StringPath regDt = createString("regDt");
 
-    public final StringPath type = createString("type");
+    public final StringPath role = createString("role");
 
     public final StringPath upDt = createString("upDt");
 

+ 5 - 0
src/main/java/com/example/ili_web/board/controller/BoardController.java

@@ -152,4 +152,9 @@ public class BoardController {
     public ResponseEntity<SuccessRes> updateComment (@RequestBody BoardReq req) {
         return ResponseEntity.ok(boardService.updateComment(req));
     }
+
+    @GetMapping("/board/chart")
+    public ResponseEntity<List<Long>> getBoardChart() {
+        return ResponseEntity.ok(boardService.getBoardChart());
+    }
 }

+ 3 - 0
src/main/java/com/example/ili_web/board/repository/BoardRepository.java

@@ -8,4 +8,7 @@ import org.springframework.stereotype.Repository;
 public interface BoardRepository extends JpaRepository<Board, Long> {
     long countBoardsByNickName(String nick_name);
     boolean existsBoardByIdAndPassword(Long id, String password);
+
+    long countByCommentIsNotNullAndType(String type);
+    long countByCommentIsNullAndType(String type);
 }

+ 7 - 0
src/main/java/com/example/ili_web/board/service/BoardService.java

@@ -185,4 +185,11 @@ public class BoardService {
         board.updateComment(req.getComment());
         return new SuccessRes("200", "update success");
     }
+
+    public List<Long> getBoardChart() {
+        List<Long> countList = new ArrayList<>();
+        countList.add(repository.countByCommentIsNotNullAndType("LG"));
+        countList.add(repository.countByCommentIsNullAndType("LG"));
+        return countList;
+    }
 }

+ 11 - 3
src/main/java/com/example/ili_web/config/MvcConfiguration.java → src/main/java/com/example/ili_web/config/MvcConfig.java

@@ -2,13 +2,12 @@ package com.example.ili_web.config;
 
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.CacheControl;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
-import java.util.concurrent.TimeUnit;
-
 @Configuration
-public class MvcConfiguration  implements WebMvcConfigurer {
+public class MvcConfig implements WebMvcConfigurer {
 
     @Override
     public void addResourceHandlers (final ResourceHandlerRegistry registry) {
@@ -25,4 +24,13 @@ public class MvcConfiguration  implements WebMvcConfigurer {
                 .addResourceLocations("classpath:/static/image/")
                 .setCacheControl(CacheControl.noCache());
     }
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**") // 모든 경로에 대해
+                .allowedOrigins("localhost") // 특정 출처 허용
+                .allowedMethods("GET", "POST", "PUT", "DELETE") // 특정 HTTP 메소드 허용
+                .allowedHeaders("*") // 모든 헤더 허용
+                .allowCredentials(true); // 쿠키/인증 정보 포함 허용
+    }
 }

+ 50 - 0
src/main/java/com/example/ili_web/config/SecurityConfig.java

@@ -0,0 +1,50 @@
+package com.example.ili_web.config;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+
+@Configuration
+@EnableWebSecurity
+@RequiredArgsConstructor
+public class SecurityConfig {
+
+    private final UserDetailsService service;
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+        http
+                .csrf(AbstractHttpConfigurer::disable)
+                .authorizeHttpRequests(authz -> {
+                    authz.requestMatchers("/admin/backoffice").hasRole("ADMIN")
+                            .requestMatchers("/admin/**").authenticated()
+                            .requestMatchers("/","/api/v1/**").permitAll()
+                            .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
+                            .anyRequest().permitAll();
+                })
+                .formLogin(form -> form
+                        .loginPage("/admin")
+                        .loginProcessingUrl("/login")
+                        .usernameParameter("userId")
+                        .passwordParameter("password")
+                        .defaultSuccessUrl("/admin/backoffice", true)
+                        .permitAll())
+                .logout((logoutConfig) ->logoutConfig
+                        .logoutUrl("/logout")
+                        .logoutSuccessUrl("/admin")
+                        .invalidateHttpSession(true))
+                .userDetailsService(service);
+
+        return http.build();
+    }
+
+
+
+}

+ 1 - 0
src/main/java/com/example/ili_web/main/controller/MainController.java

@@ -98,6 +98,7 @@ public class MainController {
     @GetMapping("/admin/backoffice")
     public String backOffice () {
         log.info("========== Move to backOffice ==========");
+        /*return HTML_PATH + "admin/backoffice.html";*/
         return HTML_PATH + "admin/backoffice.html";
     }
 }

+ 2 - 2
src/main/java/com/example/ili_web/member/controller/MemberController.java

@@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.RequestBody;
 public class MemberController {
 
     private final MemberService memberService;
-    @PostMapping("/login")
+    /*@PostMapping("/login")
     public ResponseEntity login (@RequestBody LoginReq req) {
         return memberService.login(req);
-    }
+    }*/
 }

+ 46 - 2
src/main/java/com/example/ili_web/member/domain/Member.java

@@ -4,12 +4,22 @@ import jakarta.persistence.*;
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.io.Serial;
+import java.util.Collection;
+import java.util.List;
 
 @Getter
 @Entity
 @NoArgsConstructor( access = AccessLevel.PROTECTED)
 @Table(name="MEMBER")
-public class Member {
+public class Member implements UserDetails {
+    @Serial
+    private static final long serialVersionUID = 1L;
+
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
@@ -25,11 +35,45 @@ public class Member {
     @Column
     private String address;
     @Column
-    private String type;
+    private String role;
     @Column
     private String useYn;
     @Column
     private String regDt;
     @Column
     private String upDt;
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+
+        return List.of(new SimpleGrantedAuthority("ROLE_" + role));
+    }
+
+    @Override
+    public String getUsername() {
+        return userId;
+    }
+    @Override
+    public String getPassword() {
+        return password;
+    }
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
 }

+ 4 - 0
src/main/java/com/example/ili_web/security/CustomAuthFilter.java

@@ -0,0 +1,4 @@
+package com.example.ili_web.security;
+
+public class CustomAuthFilter {
+}

+ 30 - 0
src/main/java/com/example/ili_web/security/LoginProvider.java

@@ -0,0 +1,30 @@
+/*
+package com.example.ili_web.security;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.stereotype.Service;
+
+@RequiredArgsConstructor
+@Service
+@Slf4j
+public class LoginProvider implements AuthenticationProvider {
+    private final UserDetailsService memberService;
+    @Override
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+        String userId = authentication.getName();
+        UserDetails memberDetail = memberService.loadUserByUsername(userId);
+        return null;
+    }
+
+    @Override
+    public boolean supports(Class<?> authentication) {
+        return false;
+    }
+}
+*/

+ 58 - 0
src/main/java/com/example/ili_web/security/MemberDetailService.java

@@ -0,0 +1,58 @@
+/*
+package com.example.ili_web.security;
+
+import com.example.ili_web.member.domain.Member;
+import com.example.ili_web.member.repository.MemberRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+
+@Service
+@RequiredArgsConstructor
+public class MemberDetailService implements UserDetails {
+    private final MemberRepository memberRepository;
+    public Member loadUserByUsername(String userId) throws UsernameNotFoundException {
+        Member member = memberRepository.findByUserId(userId);
+        return null;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return null;
+    }
+
+    @Override
+    public String getPassword() {
+        return null;
+    }
+
+    @Override
+    public String getUsername() {
+        return null;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return false;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return false;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return false;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return false;
+    }
+}
+*/

+ 25 - 0
src/main/java/com/example/ili_web/security/UserDetailsServiceImpl.java

@@ -0,0 +1,25 @@
+package com.example.ili_web.security;
+
+import com.example.ili_web.member.repository.MemberRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+@RequiredArgsConstructor
+@Service
+public class UserDetailsServiceImpl implements UserDetailsService {
+
+    private final MemberRepository memberRepository;
+    private final PasswordEncoder encoder;
+
+    @Override
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+
+        return memberRepository.findByUserId(username);
+    }
+
+
+}

+ 1 - 1
src/main/resources/application.properties

@@ -1,5 +1,5 @@
 #spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
-logging.level.org.springframework.web=INFO
+logging.level.org.springframework.web=TRACE
 #local
 spring.datasource.url=jdbc:mysql://103.55.191.37:3306/iliweb_test?rewriteBatchedStatements=true&profileSQL=true&logger=Slf4JLogger&maxQuerySizeToLog=999999
 #server

+ 5 - 0
src/main/resources/static/css/backoffice.css

@@ -112,3 +112,8 @@ body {
         font-size: 3.5rem;
     }
 }
+
+#advice_chart {
+    width: 300px;  /* 너비 조정 */
+    height: 300px; /* 높이 조정 */
+}

+ 11 - 0
src/main/resources/static/css/index.css

@@ -134,3 +134,14 @@ body {
     text-align: center;
     margin-bottom: 80px;
 }
+
+#myBanner {
+    height: 100vh; /* 뷰포트의 전체 높이 */
+    min-height: 300px; /* 최소 높이 설정 */
+}
+
+#banner_img {
+    height: 100vh;
+    background-size: cover;
+    background-position: center;
+}

BIN
src/main/resources/static/image/banner-airplane.jpg


BIN
src/main/resources/static/image/banner-container.jpg


BIN
src/main/resources/static/image/banner-intro.jpg


BIN
src/main/resources/static/image/banner-ships.jpg


+ 46 - 0
src/main/resources/static/js/admin/adminChart.js

@@ -0,0 +1,46 @@
+async function drewChart() {
+    let ctx = document.getElementById('advice_chart');
+    let data = await getData()
+    let dataSet = {
+        labels: [
+            '미응답'
+            , '응답'
+        ],
+        datasets: [{
+            data: data,
+            backgroundColor: [
+                'rgb(255, 99, 132)',
+                'rgb(54, 162, 235)'
+            ],
+            hoverOffset: 4
+        }]
+    }
+    new Chart(ctx, {
+        type: 'pie',
+        data: dataSet,
+        options : {
+            responsive: true,
+            maintainAspectRatio: false,
+            plugins : {
+                title : {
+                    display : true,
+                    text : '문의 현황'
+                }
+            }
+        }
+    });
+}
+
+async function getData() {
+    let data = null;
+    await axios.get('/api/v1/board/chart')
+        .then(res => {
+            data = res.data;
+        })
+        .catch(error => {
+
+        });
+    return data;
+}
+
+drewChart();

+ 3 - 9
src/main/resources/static/js/admin/login.js

@@ -1,17 +1,11 @@
 async function login () {
     const id = document.getElementById('member_id').value;
     const pw = document.getElementById('member_password').value;
+    const form = document.getElementById('loginForm');
     if (id && pw) {
-      await axios.post('login', {id, pw})
-          .then(res => {
-              console.log(res);
-              location.href = '/admin/backoffice';
-          })
-          .catch(error => {
-              alert(error.response.data);
-          })
+        form.submit();
     } else {
-        alert('입력된 정보를 확인하세요.')
+        alert('입력된 정보를 확인하세요.');
     }
 
 }

+ 1 - 5
src/main/resources/templates/html/about.html

@@ -19,15 +19,11 @@
 
 <main>
     <div class="carousel slide" data-bs-ride="carousel" id="myCarousel">
-        <!--<div class="carousel-indicators">
-            <button aria-label="Slide 1" data-bs-slide-to="0" data-bs-target="#myCarousel" type="button"></button>
-            <button aria-label="Slide 2" data-bs-slide-to="1" data-bs-target="#myCarousel" type="button"></button>
-            <button aria-label="Slide 3" data-bs-slide-to="2" data-bs-target="#myCarousel" type="button"></button>
-        </div>-->
         <div class="carousel-inner">
             <div class="carousel-item active">
                 <svg aria-hidden="true" class="bd-placeholder-img" focusable="false" height="100%"
                      preserveAspectRatio="xMidYMid slice" width="100%" xmlns="http://www.w3.org/2000/svg">
+
                     <rect fill="#777" height="100%" width="100%"/>
                 </svg>
 

+ 4 - 3
src/main/resources/templates/html/admin/backoffice.html

@@ -12,8 +12,6 @@
 
 
 
-    <!-- Bootstrap core CSS -->
-    <link href="../assets/dist/css/bootstrap.min.css" rel="stylesheet">
 
     <!-- Custom styles for this template -->
     <link href="/css/backoffice.css" rel="stylesheet">
@@ -28,7 +26,7 @@
     </button>
     <div class="navbar-nav">
         <div class="nav-item text-nowrap">
-            <a class="nav-link px-3" href="#">로그아웃</a>
+            <a class="nav-link px-3" href="/logout">로그아웃</a>
         </div>
     </div>
 </header>
@@ -67,13 +65,16 @@
                 </div>
             </div>
             <div class="table-responsive" id="admin_section">
+                <canvas class="my-4 w-100" id="advice_chart"></canvas>
             </div>
 
         </main>
     </div>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
+<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
 <script src="/js/admin/adminPublic.js"></script>
+<script src="/js/admin/adminChart.js"></script>
 <script src="/js/admin/adminGetData.js"></script>
 <script src="/js/admin/adminChangeInner.js"></script>
 <script src="/js/admin/adminMakeHtml.js"></script>

+ 3 - 3
src/main/resources/templates/html/admin/login.html

@@ -20,16 +20,16 @@
 <body class="text-center">
 
 <main class="form-signin">
-    <form>
+    <form action="/login" method="post" enctype="multipart/form-data" id="loginForm">
         <img class="mb-4" src="/image/logo.png" alt="" width="200" height="57">
         <h1 class="h3 mb-3 fw-normal">로그인</h1>
 
         <div class="form-floating">
-            <input type="email" class="form-control" id="member_id" placeholder="name@example.com">
+            <input type="email" class="form-control" id="member_id" placeholder="name@example.com" name="userId">
             <label for="member_id">아이디</label>
         </div>
         <div class="form-floating">
-            <input type="password" class="form-control" id="member_password" placeholder="Password">
+            <input type="password" class="form-control" id="member_password" placeholder="Password" name="password">
             <label for="member_password">비밀번호</label>
         </div>
 

+ 0 - 5
src/main/resources/templates/html/business-sector.html

@@ -23,11 +23,6 @@
 </header>
 <main>
     <div class="carousel slide" data-bs-ride="carousel" id="myCarousel">
-        <!--<div class="carousel-indicators">
-            <button aria-label="Slide 1" data-bs-slide-to="0" data-bs-target="#myCarousel" type="button"></button>
-            <button aria-label="Slide 2" data-bs-slide-to="1" data-bs-target="#myCarousel" type="button"></button>
-            <button aria-label="Slide 3" data-bs-slide-to="2" data-bs-target="#myCarousel" type="button"></button>
-        </div>-->
         <div class="carousel-inner">
             <div class="carousel-item active">
                 <svg aria-hidden="true" class="bd-placeholder-img" focusable="false" height="100%"

+ 36 - 171
src/main/resources/templates/html/index.html

@@ -26,201 +26,66 @@
 <main>
     <!-- swiper 브로슈어 -->
     <div class="carousel slide" data-bs-ride="carousel" id="myCarousel">
-        <div class="carousel-indicators">
-            <button aria-current="true" aria-label="Slide 1" class="active" data-bs-slide-to="0"
-                    data-bs-target="#myCarousel"
-                    type="button"></button>
-            <button aria-label="Slide 2" data-bs-slide-to="1" data-bs-target="#myCarousel" type="button"></button>
-            <button aria-label="Slide 3" data-bs-slide-to="2" data-bs-target="#myCarousel" type="button"></button>
-        </div>
-        <div class="carousel-inner">
+        <div class="carousel-inner" id="myBanner">
             <div class="carousel-item active">
-                <svg aria-hidden="true" class="bd-placeholder-img" focusable="false" height="100%"
-                     preserveAspectRatio="xMidYMid slice" width="100%" xmlns="http://www.w3.org/2000/svg">
-                    <rect fill="#777" height="100%" width="100%"/>
-                </svg>
-
+                <img alt="main" src="/image/banner-ships.jpg" class="d-block w-100" id="banner_img">
                 <div class="container">
-                    <div class="carousel-caption text-start">
+                    <div class="carousel-caption">
                         <h1>국제종합물류 홈페이지를 찾아주신 여러분 환영합니다</h1>
                         <p>" 혁신경영으로 고객만족에 최선을 다하겠습니다 "</p>
-                        <p><a class="btn btn-lg btn-primary" href="/about">회사소개</a></p>
-                    </div>
-                </div>
-            </div>
-            <div class="carousel-item">
-                <svg aria-hidden="true" class="bd-placeholder-img" focusable="false" height="100%"
-                     preserveAspectRatio="xMidYMid slice" width="100%" xmlns="http://www.w3.org/2000/svg">
-                    <rect fill="#777" height="100%" width="100%"/>
-                </svg>
-
-                <div class="container">
-                    <div class="carousel-caption">
-                        <h1>Global Network</h1>
-                        <p>(주) 국제종합물류는 35년의 국제물류사업 역사를 가진 회사로</p>
-                        <p>중국을 시작으로 세계 각지에 글로벌 물류 네트워크를 구축하였고</p>
-                        <p>오랜 실무경험을 통한 노하우로 언제 어디서나 고객만족을 실현하고 있습니다.</p>
-                        <p><a class="btn btn-lg btn-primary" href="#">물류망</a></p>
-                    </div>
-                </div>
-            </div>
-            <div class="carousel-item">
-                <svg aria-hidden="true" class="bd-placeholder-img" focusable="false" height="100%"
-                     preserveAspectRatio="xMidYMid slice" width="100%" xmlns="http://www.w3.org/2000/svg">
-                    <rect fill="#777" height="100%" width="100%"/>
-                </svg>
-
-                <div class="container">
-                    <div class="carousel-caption text-end">
-                        <h1>IL Logstics Competitive edge</h1>
-                        <p>IL Logistics는 급변하는 글로벌 경쟁시장에서</p>
-                        <p>고객의 실제적 상황에 따라 최적의 물류써비스를 제공하여</p>
-                        <p>고객의 이익극대화에 최선을 다하고 있습니다</p>
-                        <p><a class="btn btn-lg btn-primary" href="/business-sector">사업영역</a></p>
                     </div>
                 </div>
             </div>
         </div>
-        <button class="carousel-control-prev" data-bs-slide="prev" data-bs-target="#myCarousel" type="button">
-            <span aria-hidden="true" class="carousel-control-prev-icon"></span>
-            <span class="visually-hidden">Previous</span>
-        </button>
-        <button class="carousel-control-next" data-bs-slide="next" data-bs-target="#myCarousel" type="button">
-            <span aria-hidden="true" class="carousel-control-next-icon"></span>
-            <span class="visually-hidden">Next</span>
-        </button>
-    </div>
 
 
-    <!-- Marketing messaging and featurettes
-    ================================================== -->
-    <!-- Wrap the rest of the page in another container to center all the content. -->
+        <div class="container marketing">
+            <hr class="featurette-divider" style="visibility: hidden">
 
-    <div class="container marketing">
-        <!-- 업무 영역 -->
-        <div class="row">
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="항공운송" height="140" src="/image/work/airplane.svg" class="img-fluid">
-                <p class="text-center">항공운송</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="해상운송" height="140" src="/image/work/ship.svg" class="img-fluid">
-                <p class="text-center">해상운송</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="국제특송" height="140" src="/image/work/international-logistics.svg" class="img-fluid">
-                <p class="text-center">국제특송</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="특수화물" height="140" src="/image/work/special-cargo.svg" class="img-fluid">
-                <p class="text-center">특수화물</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="통관/관세환급" height="140" src="/image/work/tax-refund.svg" class="img-fluid">
-                <p class="text-center">통관/관세환급</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="물류컨설팅" height="140" src="/image/work/consulting.svg" class="img-fluid">
-                <p class="text-center">물류컨설팅</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="육상운송" height="140" src="/image/work/container-truck.svg" class="img-fluid">
-                <p class="text-center">육상운송</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="철도운송" height="140" src="/image/work/train.svg" class="img-fluid">
-                <p class="text-center">철도운송</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="전자상거래" height="140" src="/image/work/ecommerce.svg" class="img-fluid">
-                <p class="text-center">전자상거래</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="창고보관" height="140" src="/image/work/warehouse.svg" class="img-fluid">
-                <p class="text-center">창고보관</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="유통물류" height="140" src="/image/work/logistics-boxes.svg" class="img-fluid">
-                <p class="text-center">유통물류</p>
-            </div>
-            <div class="col-2 d-flex flex-column align-items-center">
-                <img alt="무역컨설팅" height="140" src="/image/work/handshake.svg" class="img-fluid">
-                <p class="text-center">무역컨설팅</p>
-            </div>
-        </div><!-- /.row -->
-
-        <hr class="featurette-divider">
-
-        <!--  nation swiper start -->
-        <div class="container nation">
-            <div class="cp-12"><p>세계 각국이 선택한 국제종합물류</p></div>
-
-            <div class="swiper-container">
-                <div class="swiper-wrapper">
-                    <div class="swiper-slide"><img alt="호주" src="/image/nation/australia.svg"></div>
-                    <div class="swiper-slide"><img alt="브라질" src="/image/nation/brazil.svg"></div>
-                    <div class="swiper-slide"><img alt="중국" src="/image/nation/china.svg"></div>
-                    <div class="swiper-slide"><img alt="콜롬비아" src="/image/nation/colombia.svg"></div>
-                    <div class="swiper-slide"><img alt="프랑스" src="/image/nation/france.svg"></div>
-                    <div class="swiper-slide"><img alt="인도" src="/image/nation/india.svg"></div>
-                    <div class="swiper-slide"><img alt="이탈리아" src="/image/nation/italy.svg"></div>
-                    <div class="swiper-slide"><img alt="파키스탄" src="/image/nation/pakistan.svg"></div>
-                    <div class="swiper-slide"><img alt="페루" src="/image/nation/peru.svg"></div>
-                    <div class="swiper-slide"><img alt="카타르" src="/image/nation/qatar.svg"></div>
-                    <div class="swiper-slide"><img alt="스페인" src="/image/nation/spain.svg"></div>
-                    <div class="swiper-slide"><img alt="탄자니아" src="/image/nation/tanzania.svg"></div>
-                    <div class="swiper-slide"><img alt="베트남" src="/image/nation/vietnam.svg"></div>
+            <div class="row featurette">
+                <div class="col-md-7">
+                    <h2 class="featurette-heading">One-Stop <br/>Service</h2>
+                    <p class="lead">물류라이센스를 통해 물류 전 과정을 아우르는 원스톱 물류서비스를 제공함으로써 물류비용 절감 및 효율성 향상에 기여하고 있습니다.</p>
+                </div>
+                <div class="col-md-5">
+                    <img alt="one-stop" src="/image/service_category/onestop.jpg">
                 </div>
             </div>
-        </div>
-
-        <hr class="featurette-divider">
 
-        <div class="row featurette">
-            <div class="col-md-7">
-                <h2 class="featurette-heading">One-Stop <br/>Service</h2>
-                <p class="lead">물류라이센스를 통해 물류 전 과정을 아우르는 원스톱 물류서비스를 제공함으로써 물류비용 절감 및 효율성 향상에 기여하고 있습니다.</p>
-            </div>
-            <div class="col-md-5">
-                <img alt="one-stop" src="/image/service_category/onestop.jpg">
-            </div>
-        </div>
+            <hr class="featurette-divider">
 
-        <hr class="featurette-divider">
+            <div class="row featurette">
+                <div class="col-md-5">
+                    <img alt="one-stop" src="/image/service_category/wins.png">
+                </div>
+                <div class="col-md-7">
+                    <h2 class="featurette-heading">Worldwide Information<br/>Network System</h2>
+                    <p class="lead">물류라이센스를 통해 물류 전 과정을 아우르는 원스톱 물류서비스를 제공함으로써 물류비용 절감 및 효율성 향상에 기여하고 있습니다.</p>
+                </div>
 
-        <div class="row featurette">
-            <div class="col-md-5">
-                <img alt="one-stop" src="/image/service_category/wins.png">
-            </div>
-            <div class="col-md-7">
-                <h2 class="featurette-heading">Worldwide Information<br/>Network System</h2>
-                <p class="lead">물류라이센스를 통해 물류 전 과정을 아우르는 원스톱 물류서비스를 제공함으로써 물류비용 절감 및 효율성 향상에 기여하고 있습니다.</p>
             </div>
 
-        </div>
-
-        <hr class="featurette-divider">
+            <hr class="featurette-divider">
 
-        <div class="row featurette">
-            <div class="col-md-7">
-                <h2 class="featurette-heading">Global<br/>Networks</h2>
-                <p class="lead">급변하는 글로벌 환경 속에서 국경을 초월한 물류 네트워크를 구축하여 고객의 물류 경쟁력 향상에 기여합니다.</p>
-            </div>
-            <div class="col-md-5">
-                <img alt="one-stop" src="/image/service_category/global.jpg">
+            <div class="row featurette">
+                <div class="col-md-7">
+                    <h2 class="featurette-heading">Global<br/>Networks</h2>
+                    <p class="lead">급변하는 글로벌 환경 속에서 국경을 초월한 물류 네트워크를 구축하여 고객의 물류 경쟁력 향상에 기여합니다.</p>
+                </div>
+                <div class="col-md-5">
+                    <img alt="one-stop" src="/image/service_category/global.jpg">
+                </div>
             </div>
-        </div>
 
-        <hr class="featurette-divider">
+            <hr class="featurette-divider">
 
-        <!-- /END THE FEATURETTES -->
 
-    </div><!-- /.container -->
+        </div><!-- /.container -->
 
+    </div>
+        <footer class="footer" th:include="html/common/footer">
 
-    <footer class="footer" th:include="html/common/footer">
-
-    </footer>
+        </footer>
 </main>
 
 </body>
@@ -232,5 +97,5 @@
 
 <script src="https://stackpath.bootstrapcdn.com/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
 <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
-<script src="/js/swiper/swiper.js"></script>
+<!--<script src="/js/swiper/swiper.js"></script>-->
 </html>