Compare commits
8 Commits
77c0a7d43f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37bc3f423c | ||
|
|
69d84c4706 | ||
| d84a3313e3 | |||
|
|
f786df1d9b | ||
|
|
40a1c2740d | ||
|
|
dae8e6d3a7 | ||
|
|
505a3e5101 | ||
|
|
a697185451 |
40
java/README.md
Normal file
40
java/README.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
### 기본 환경
|
||||||
|
- Java 11
|
||||||
|
- MyBatis 4.x
|
||||||
|
- JPA 2.2
|
||||||
|
- QueryDSL 5.0
|
||||||
|
|
||||||
|
### 개발 규약
|
||||||
|
- 사용하지 않는 Parameter는 넣지 않는다.
|
||||||
|
- Request, Response 호출은 EgovRequestUtils을 통해서만 한다.
|
||||||
|
- 관리자 Session 정보는 EgovAdminSessionUtils로 호출한다.(MultipartRequest는 제외)
|
||||||
|
- 사용자 Session 정보는 EgovUserSessionUtils로 호출한다.
|
||||||
|
- Spring context에서 벗어나게 개발하지 않는다.
|
||||||
|
|
||||||
|
### 어노테이션
|
||||||
|
- API Controller: @RestController
|
||||||
|
- Page Controller: @Controller
|
||||||
|
- Service: @Service
|
||||||
|
- Mapper: @Mapper
|
||||||
|
- DAO 또는 별도 컴포넌트들: @Component
|
||||||
|
|
||||||
|
### API URL 규약
|
||||||
|
- 대국민포털(prefix): 없음
|
||||||
|
- 참여기관/관리자포털(prefix): /admin
|
||||||
|
- 페이지: /**
|
||||||
|
- api: /api/**
|
||||||
|
- 메뉴 등록 시 full url로 기재할 것!
|
||||||
|
- 페이지 메뉴는 도메인으로 분기 처리되므로 동일 URL 사용 가능
|
||||||
|
- id 조회의 경우 반드시 query 처리할 것!
|
||||||
|
|
||||||
|
|
||||||
|
### DB 암호화
|
||||||
|
- 환경변수 추가 필요(안하면 에러 남)
|
||||||
|
- {project.baseDir}/main/resources/ksing/db 에 있는 모든 파일을 C:\SecureDBAgent 에 복사
|
||||||
|
- 아래의 정보로 환경변수 세팅 진행
|
||||||
|
- SDB_HOME / C:\SecureDBAgent
|
||||||
|
- SDB_FIRST_PORT / 9909
|
||||||
|
|
||||||
|
### 비지니스 로직 로깅 관련
|
||||||
|
- [필수] 비지니스 로직에 로깅할 경우 class 상단에 @Slf4j 어노테이션 선언
|
||||||
|
- [필수] Service에서는 전자정부프레임워크에서 제공하는 egovLogger를 사용
|
||||||
29
java/git.md
Normal file
29
java/git.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
### 임시 git 설정(SSH 터널링)
|
||||||
|
```
|
||||||
|
ssh -i KLAC_SYS_ADM.pem -o ServerAliveInterval=60 -L 8081:localhost:8081 -L 5000:localhost:3000 rocky@192.168.30.7 -p 6722
|
||||||
|
```
|
||||||
|
|
||||||
|
### 브랜치 용도
|
||||||
|
- master: 운영 서버 반영 브랜치
|
||||||
|
- dev: 개발 서버 반영 브랜치
|
||||||
|
- mix: 개발용 브랜치
|
||||||
|
|
||||||
|
### 신규 브랜치 작성 방법
|
||||||
|
- feature/gitea아이디/번호
|
||||||
|
- 예) feature/natoro/1
|
||||||
|
- push 할 때마다 뒷 번호는 증가
|
||||||
|
|
||||||
|
### git 사용 방법
|
||||||
|
1. 작업하기 전 반드시 mix 브랜치에서 new branch로 생성
|
||||||
|
2. 작업이 완료될 경우 반드시 commit
|
||||||
|
3. 새로운 내용을 받을 때 pull(예: mix 브랜치 pull)
|
||||||
|
4. 작업한 내용을 서버에 올릴 때 push
|
||||||
|
5. 개발자는 merge 작업하지 말 것!
|
||||||
|
6. 작업 단위는 작게 진행(기능별로 분리해서 branch 작업)
|
||||||
|
7. 커미터, 기능별 태그 관리 및 버전 관리할 것
|
||||||
|
|
||||||
|
### 소스 관리 및 반영 관리(수정)
|
||||||
|
1. pull request 처리 주기
|
||||||
|
2. 코드 리뷰 주기
|
||||||
|
3. 반영 주기
|
||||||
|
4. 예) 수요일 - 오후 4시 pull request 처리
|
||||||
8
java/mapper.md
Normal file
8
java/mapper.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Mapper 사용 시 아래와 같이 작성(중괄호는 치환되는 명칭)
|
||||||
|
|
||||||
|
```
|
||||||
|
package: egovframework.com.lasp.{업무명}.mapper
|
||||||
|
Mapper파일명: {Admin | User}{업무명}Mapper.xml
|
||||||
|
annotation: org.egovframe.rte.psl.dataaccess.mapper.Mapper
|
||||||
|
xml파일: \resources\egovframework\sqlmap\mappers\{Mapper명과 동일}.xml
|
||||||
|
```
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.leejk0523.javavue.admin.contents.controller;
|
package com.leejk0523.javavue.admin.contents.controller;
|
||||||
|
|
||||||
import com.leejk0523.javavue.admin.contents.service.AdminContentsService;
|
import com.leejk0523.javavue.admin.contents.service.AdminContentsService;
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsListResult;
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsPagingQuery;
|
||||||
import com.leejk0523.javavue.model.AsaContent;
|
import com.leejk0523.javavue.model.AsaContent;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -15,8 +18,8 @@ public class AdminContentsController {
|
|||||||
private final AdminContentsService adminContentsService;
|
private final AdminContentsService adminContentsService;
|
||||||
|
|
||||||
@GetMapping("/api/admin/contents/contentsList")
|
@GetMapping("/api/admin/contents/contentsList")
|
||||||
public ResponseEntity<List<AsaContent>> siteAllList() {
|
public ResponseEntity<Page<ContentsListResult>> findContentsList(ContentsPagingQuery query) {
|
||||||
final var results = adminContentsService.SiteAllList();
|
final var results = adminContentsService.findContentsList(query);
|
||||||
return ResponseEntity.ok(results);
|
return ResponseEntity.ok(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,20 @@
|
|||||||
package com.leejk0523.javavue.admin.contents.dao;
|
package com.leejk0523.javavue.admin.contents.dao;
|
||||||
|
|
||||||
|
import ch.qos.logback.core.util.StringUtil;
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsListResult;
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsPagingQuery;
|
||||||
|
import com.leejk0523.javavue.common.QueryDSLUtils;
|
||||||
import com.leejk0523.javavue.model.AsaContent;
|
import com.leejk0523.javavue.model.AsaContent;
|
||||||
import com.leejk0523.javavue.model.QAsaContent;
|
import com.leejk0523.javavue.model.QAsaContent;
|
||||||
|
import com.querydsl.core.types.Projections;
|
||||||
|
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||||
|
|
||||||
|
import com.querydsl.core.types.dsl.Expressions;
|
||||||
|
import io.micrometer.common.util.StringUtils;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageImpl;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
|
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@@ -9,15 +22,63 @@ import java.util.List;
|
|||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public class AdminContentsDao extends QuerydslRepositorySupport {
|
public class AdminContentsDao extends QuerydslRepositorySupport {
|
||||||
|
|
||||||
public AdminContentsDao() {
|
public AdminContentsDao() {
|
||||||
super(AsaContent.class);
|
super(AsaContent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AsaContent> SiteAllList() {
|
public Page<ContentsListResult> findContentsList(ContentsPagingQuery query) {
|
||||||
QAsaContent asaContent = QAsaContent.asaContent;
|
QAsaContent asaContent = QAsaContent.asaContent;
|
||||||
|
|
||||||
return from(asaContent)
|
final var offset = QueryDSLUtils.getOffset(query);
|
||||||
.fetch();
|
final var limit = QueryDSLUtils.getLimit(query);
|
||||||
|
final var pageable = QueryDSLUtils.getPageable(query);
|
||||||
|
|
||||||
|
BooleanExpression expression = asaContent.delYn.eq("N");
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(query.getKeyword())) {
|
||||||
|
switch (query.getType()) {
|
||||||
|
case CONTENT: {
|
||||||
|
expression = expression.and(asaContent.contents.contains(query.getKeyword()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TITLE : {
|
||||||
|
expression = expression.and(asaContent.contentTitle.contains(query.getKeyword()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOTAL: {
|
||||||
|
expression = expression.and(asaContent.contents.contains(query.getKeyword())
|
||||||
|
.or(asaContent.contentTitle.contains(query.getKeyword())));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(query.getOrgId())) {
|
||||||
|
expression = expression.and(asaContent.orgId.eq(query.getOrgId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
final var list = from(asaContent)
|
||||||
|
.select(
|
||||||
|
Projections.bean(
|
||||||
|
ContentsListResult.class,
|
||||||
|
asaContent.contentId,
|
||||||
|
asaContent.contentTitle,
|
||||||
|
asaContent.orgId,
|
||||||
|
asaContent.useYn,
|
||||||
|
asaContent.frstRgtrId,
|
||||||
|
asaContent.frstRegDt,
|
||||||
|
asaContent.lastMdfrId,
|
||||||
|
asaContent.lastMdfcnDt
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.where(expression)
|
||||||
|
.limit(limit)
|
||||||
|
.offset(offset)
|
||||||
|
.orderBy(asaContent.contentId.desc())
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
final var total = from(asaContent).where(expression).fetchCount();
|
||||||
|
|
||||||
|
return new PageImpl<>(list, pageable, total);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.leejk0523.javavue.admin.contents.service;
|
package com.leejk0523.javavue.admin.contents.service;
|
||||||
|
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsListResult;
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsPagingQuery;
|
||||||
import com.leejk0523.javavue.model.AsaContent;
|
import com.leejk0523.javavue.model.AsaContent;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface AdminContentsService {
|
public interface AdminContentsService {
|
||||||
List<AsaContent> SiteAllList();
|
Page<ContentsListResult> findContentsList(ContentsPagingQuery query);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.leejk0523.javavue.admin.contents.service;
|
package com.leejk0523.javavue.admin.contents.service;
|
||||||
|
|
||||||
import com.leejk0523.javavue.admin.contents.dao.AdminContentsDao;
|
import com.leejk0523.javavue.admin.contents.dao.AdminContentsDao;
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsListResult;
|
||||||
|
import com.leejk0523.javavue.admin.contents.vo.ContentsPagingQuery;
|
||||||
import com.leejk0523.javavue.model.AsaContent;
|
import com.leejk0523.javavue.model.AsaContent;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -13,7 +16,7 @@ public class AdminContentsServiceImpl implements AdminContentsService {
|
|||||||
private final AdminContentsDao adminContentsDao;
|
private final AdminContentsDao adminContentsDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AsaContent> SiteAllList() {
|
public Page<ContentsListResult> findContentsList(ContentsPagingQuery query) {
|
||||||
return adminContentsDao.SiteAllList();
|
return adminContentsDao.findContentsList(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.leejk0523.javavue.admin.contents.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ContentsListResult {
|
||||||
|
private Integer contentId;
|
||||||
|
private String contentTitle;
|
||||||
|
private String orgId;
|
||||||
|
private String useYn;
|
||||||
|
private String frstRgtrId;
|
||||||
|
private LocalDateTime frstRegDt;
|
||||||
|
private String lastMdfrId;
|
||||||
|
private LocalDateTime lastMdfcnDt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.leejk0523.javavue.admin.contents.vo;
|
||||||
|
|
||||||
|
import com.leejk0523.javavue.common.PagingQuery;
|
||||||
|
import lombok.Data;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ContentsPagingQuery implements PagingQuery {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private int page;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
private String orgId;
|
||||||
|
private String siteId;
|
||||||
|
private String keyword;
|
||||||
|
private Type type;
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
TITLE,
|
||||||
|
CONTENT,
|
||||||
|
TOTAL
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.leejk0523.javavue.code.dao;
|
||||||
|
|
||||||
|
import com.leejk0523.javavue.common.GridCode;
|
||||||
|
import com.leejk0523.javavue.model.ComCd;
|
||||||
|
import com.leejk0523.javavue.model.QAsaSite;
|
||||||
|
import com.leejk0523.javavue.model.QIstInst;
|
||||||
|
import com.querydsl.core.types.Projections;
|
||||||
|
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CodeDAO extends QuerydslRepositorySupport {
|
||||||
|
public CodeDAO() {
|
||||||
|
super(ComCd.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GridCode> findSiteCodeList() {
|
||||||
|
final var site = QAsaSite.asaSite;
|
||||||
|
|
||||||
|
return from(site)
|
||||||
|
.select(
|
||||||
|
Projections.bean(
|
||||||
|
GridCode.class,
|
||||||
|
site.siteId.as("value"),
|
||||||
|
site.siteName.as("text"),
|
||||||
|
site.siteName.as("label")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GridCode> findInstCodeList() {
|
||||||
|
final var inst = QIstInst.istInst;
|
||||||
|
|
||||||
|
return from(inst)
|
||||||
|
.select(
|
||||||
|
Projections.bean(
|
||||||
|
GridCode.class,
|
||||||
|
inst.instNo.as("value"),
|
||||||
|
inst.instNm.as("label"),
|
||||||
|
inst.instNm.as("text")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.fetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.leejk0523.javavue.code.service;
|
||||||
|
|
||||||
|
import com.leejk0523.javavue.common.GridCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface CodeService {
|
||||||
|
List<GridCode> findSiteCodeList();
|
||||||
|
List<GridCode> findInstCodeList();
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.leejk0523.javavue.code.service.impl;
|
||||||
|
|
||||||
|
import com.leejk0523.javavue.code.dao.CodeDAO;
|
||||||
|
import com.leejk0523.javavue.code.service.CodeService;
|
||||||
|
import com.leejk0523.javavue.common.GridCode;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service("lasp.codeServiceImpl")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CodeServiceImpl implements CodeService {
|
||||||
|
private final CodeDAO codeDAO;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GridCode> findSiteCodeList() {
|
||||||
|
return codeDAO.findSiteCodeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GridCode> findInstCodeList() {
|
||||||
|
return codeDAO.findInstCodeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.leejk0523.javavue.code.web;
|
||||||
|
|
||||||
|
import com.leejk0523.javavue.code.service.CodeService;
|
||||||
|
import com.leejk0523.javavue.common.GridCode;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CodeController {
|
||||||
|
|
||||||
|
private final CodeService codeService;
|
||||||
|
|
||||||
|
@GetMapping("/api/admin/code/siteList")
|
||||||
|
public ResponseEntity<List<GridCode>> siteCodeList() {
|
||||||
|
final var results = codeService.findSiteCodeList();
|
||||||
|
return ResponseEntity.ok(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/api/admin/code/instList")
|
||||||
|
public ResponseEntity<List<GridCode>> instCodeList() {
|
||||||
|
final var results = codeService.findInstCodeList();
|
||||||
|
return ResponseEntity.ok(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.leejk0523.javavue.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class GridCode {
|
||||||
|
private String label;
|
||||||
|
private String text;
|
||||||
|
private String value;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.leejk0523.javavue.common;
|
||||||
|
|
||||||
|
public interface PagingQuery {
|
||||||
|
int getPage();
|
||||||
|
int getSize();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.leejk0523.javavue.common;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
|
public class QueryDSLUtils {
|
||||||
|
public static Pageable getPageable(PagingQuery query) {
|
||||||
|
return PageRequest.of(query.getPage() - 1, query.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getOffset(PagingQuery query) {
|
||||||
|
return (long) (query.getPage() - 1) * query.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getLimit(PagingQuery query) {
|
||||||
|
return query.getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,18 +10,15 @@ import java.time.LocalDateTime;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "asa_content")
|
@Table(name = "ASA_CONTENT")
|
||||||
public class AsaContent {
|
public class AsaContent {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@SequenceGenerator(name = "SQ_ASA_CONTENT", sequenceName = "SQ_ASA_CONTENT", allocationSize = 1)
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQ_ASA_CONTENT")
|
||||||
@Column(name = "CONTENT_ID", nullable = false)
|
@Column(name = "CONTENT_ID", nullable = false)
|
||||||
private Integer contentId;
|
private Integer contentId;
|
||||||
|
|
||||||
@Size(max = 20)
|
|
||||||
@Column(name = "SITE_ID", length = 20)
|
|
||||||
private String siteId;
|
|
||||||
|
|
||||||
@Column(name = "ORG_ID", length = 36)
|
@Column(name = "ORG_ID", length = 36)
|
||||||
private String orgId;
|
private String orgId;
|
||||||
|
|
||||||
@@ -38,10 +35,10 @@ public class AsaContent {
|
|||||||
private String contentPlain;
|
private String contentPlain;
|
||||||
|
|
||||||
@Column(name = "USE_YN", length = 1, nullable = false)
|
@Column(name = "USE_YN", length = 1, nullable = false)
|
||||||
private Boolean useYn;
|
private String useYn;
|
||||||
|
|
||||||
@Column(name = "DEL_YN", length = 1, nullable = false)
|
@Column(name = "DEL_YN", length = 1, nullable = false)
|
||||||
private Boolean delYn;
|
private String delYn;
|
||||||
|
|
||||||
@Column(name = "FRST_RGTR_ID", length = 50, nullable = false)
|
@Column(name = "FRST_RGTR_ID", length = 50, nullable = false)
|
||||||
private String frstRgtrId;
|
private String frstRgtrId;
|
||||||
|
|||||||
110
java/src/main/java/com/leejk0523/javavue/model/ComCd.java
Normal file
110
java/src/main/java/com/leejk0523/javavue/model/ComCd.java
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
package com.leejk0523.javavue.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Entity
|
||||||
|
@Table(name = "com_cd")
|
||||||
|
@IdClass(ComCd.Key.class)
|
||||||
|
public class ComCd {
|
||||||
|
@Id
|
||||||
|
@NotNull
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "CD_GROUP_ID", nullable = false, length = 20)
|
||||||
|
private String cdGroupId;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Size(max = 6)
|
||||||
|
@NotNull
|
||||||
|
@Column(name = "COM_CD", nullable = false, length = 6)
|
||||||
|
private String comCd;
|
||||||
|
|
||||||
|
@Size(max = 100)
|
||||||
|
@Column(name = "COM_CD_NM", length = 100)
|
||||||
|
private String comCdNm;
|
||||||
|
|
||||||
|
@Size(max = 2000)
|
||||||
|
@Column(name = "COM_CD_EXPLN", length = 2000)
|
||||||
|
private String comCdExpln;
|
||||||
|
|
||||||
|
@Column(name = "SORT_SEQ", nullable = false)
|
||||||
|
private Integer sortSeq;
|
||||||
|
|
||||||
|
@Column(name = "USE_YN", length = 1, nullable = false)
|
||||||
|
private String useYn;
|
||||||
|
|
||||||
|
@Column(name = "DEL_YN", length = 1, nullable = false)
|
||||||
|
private String delYn;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM1", length = 20)
|
||||||
|
private String artclNm1;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM2", length = 20)
|
||||||
|
private String artclNm2;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM3", length = 20)
|
||||||
|
private String artclNm3;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM4", length = 20)
|
||||||
|
private String artclNm4;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM5", length = 20)
|
||||||
|
private String artclNm5;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM6", length = 20)
|
||||||
|
private String artclNm6;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM7", length = 20)
|
||||||
|
private String artclNm7;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM8", length = 20)
|
||||||
|
private String artclNm8;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM9", length = 20)
|
||||||
|
private String artclNm9;
|
||||||
|
|
||||||
|
@Size(max = 20)
|
||||||
|
@Column(name = "ARTCL_NM10", length = 20)
|
||||||
|
private String artclNm10;
|
||||||
|
|
||||||
|
@Column(name = "FRST_RGTR_ID", length = 50, nullable = false)
|
||||||
|
private String frstRgtrId;
|
||||||
|
|
||||||
|
@Column(name = "FRST_REG_DT", nullable = false)
|
||||||
|
private LocalDateTime frstRegDt;
|
||||||
|
|
||||||
|
@Column(name = "LAST_MDFR_ID", length = 50)
|
||||||
|
private String lastMdfrId;
|
||||||
|
|
||||||
|
@Column(name = "LAST_MDFCN_DT")
|
||||||
|
private LocalDateTime lastMdfcnDt;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Key implements Serializable {
|
||||||
|
private static final long serialVersionUID = -3281903370957728656L;
|
||||||
|
private String cdGroupId;
|
||||||
|
private String comCd;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
52
java/src/main/java/com/leejk0523/javavue/model/IstInst.java
Normal file
52
java/src/main/java/com/leejk0523/javavue/model/IstInst.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package com.leejk0523.javavue.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Entity
|
||||||
|
@Table(name = "IST_INST")
|
||||||
|
public class IstInst {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "INST_NO", length = 10, nullable = false)
|
||||||
|
private String instNo;
|
||||||
|
|
||||||
|
@Column(name = "INST_CLSF_CD", length = 6, nullable = false)
|
||||||
|
private String instClsfCd;
|
||||||
|
|
||||||
|
@Column(name = "INST_NM", length = 200, nullable = false)
|
||||||
|
private String instNm;
|
||||||
|
|
||||||
|
@Column(name = "INST_SRVC_EXPLN", length = 50)
|
||||||
|
private String instSrvcExpln;
|
||||||
|
|
||||||
|
@Column(name = "INST_CN")
|
||||||
|
private String instCn;
|
||||||
|
|
||||||
|
@Column(name = "ATCH_FILE_ID", length = 20)
|
||||||
|
private String atchFileId;
|
||||||
|
|
||||||
|
@Column(name = "USE_YN", length = 1, nullable = false)
|
||||||
|
private String useYn;
|
||||||
|
|
||||||
|
@Column(name = "FRST_RGTR_ID", length = 50, nullable = false)
|
||||||
|
private String frstRgtrId;
|
||||||
|
|
||||||
|
@Column(name = "FRST_REG_DT", nullable = false)
|
||||||
|
private LocalDateTime frstRegDt;
|
||||||
|
|
||||||
|
@Column(name = "LAST_MDFR_ID", length = 50)
|
||||||
|
private String lastMdfrId;
|
||||||
|
|
||||||
|
@Column(name = "LAST_MDFCN_DT")
|
||||||
|
private LocalDateTime lastMdfcnDt;
|
||||||
|
}
|
||||||
@@ -7,4 +7,16 @@ spring.datasource.password=Ghtkssk0325
|
|||||||
|
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
spring.jpa.properties.hibernate.show-sql=true
|
spring.jpa.properties.hibernate.show-sql=true
|
||||||
|
# SQL 출력
|
||||||
|
#spring.jpa.show-sql=true
|
||||||
|
|
||||||
|
# SQL 포맷팅
|
||||||
spring.jpa.properties.hibernate.format_sql=true
|
spring.jpa.properties.hibernate.format_sql=true
|
||||||
|
spring.jpa.properties.hibernate.type=trace
|
||||||
|
|
||||||
|
# 바인딩 파라미터 값 로깅
|
||||||
|
logging.level.org.hibernate.type.descriptor.sql=TRACE
|
||||||
|
|
||||||
|
# SQL에 바인딩된 파라미터 값도 출력
|
||||||
|
logging.level.org.hibernate.SQL=DEBUG
|
||||||
|
|
||||||
|
|||||||
114
nuxt/README.md
114
nuxt/README.md
@@ -1,75 +1,71 @@
|
|||||||
# Nuxt Minimal Starter
|
### 기본 환경
|
||||||
|
- vue 3.x(5.0.8)
|
||||||
|
- node (v20.17.0)
|
||||||
|
- vue-router(최신)
|
||||||
|
- pinia(최신) - store
|
||||||
|
- Nuxt(최신) - 프레임워크
|
||||||
|
- antd 4.x - UI/UX
|
||||||
|
- yarn (1.22.22)
|
||||||
|
- 추후 환경은 변경될 수 있음
|
||||||
|
|
||||||
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
## 최초 세팅
|
||||||
|
- terminal(혹은 command창): yarn install
|
||||||
|
- 실행 시 yarn dev
|
||||||
|
|
||||||
## Setup
|
## 개발 시 중요 사항
|
||||||
|
- 모든 파일은 업무 기준으로 작성됨(예: 사용자 > user)
|
||||||
|
- 공통사항으로 적용되는 경우 utils 사용할 것!
|
||||||
|
- 모든 네이밍은 명확한 단어로 사용할 것!
|
||||||
|
- 반드시 저장할 경우 Eslint, Prettier 적용
|
||||||
|
|
||||||
Make sure to install dependencies:
|
## 공통 단어 주의사항
|
||||||
|
- 비즈니스 로직은 공통이 아님(불허)
|
||||||
|
- 공통은 언제든지 사용할 수 있는 라이브러리성을 말하는 것임
|
||||||
|
|
||||||
```bash
|
## Commit 금지 파일 및 디렉토리
|
||||||
# npm
|
- /node_modules/
|
||||||
npm install
|
- 기타 IDE 환경 파일(.classpath 등등)
|
||||||
|
|
||||||
# pnpm
|
### 페이지 작성
|
||||||
pnpm install
|
- pages/도메인/index.vue
|
||||||
|
- 페이지는 controller와 같은 역할을 함
|
||||||
|
- useHead를 이용하여 html head 영역을 설정함
|
||||||
|
|
||||||
# yarn
|
### 페이지 내 컴포넌트
|
||||||
yarn install
|
- /src/components/도메인/컴포넌트명.vue
|
||||||
|
|
||||||
# bun
|
### store 작성 위치
|
||||||
bun install
|
- 디렉토리: /src/stores/도메인/index.ts
|
||||||
|
|
||||||
|
### api 작성 위치
|
||||||
|
- 디렉토리: /src/apis/도메인/index.ts
|
||||||
|
|
||||||
|
### Type 지정
|
||||||
|
- type 및 interface로 타입을 지정하는 경우가 많음
|
||||||
|
- 법률구조공단은 type으로 모든 객체의 타입을 지정하는 것을 원칙으로 함
|
||||||
|
- 최대한 undefined를 사용하지 않는 선으로 개발할 것
|
||||||
|
- 예로 userId: string의 경우 빈값을 표현할 때 userId: '' 형식으로 사용할 것!
|
||||||
|
- 타입 import 시 아래와 같이 type을 지정해야 함
|
||||||
|
```
|
||||||
|
import type {UserItemType} from 'types'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development Server
|
|
||||||
|
|
||||||
Start the development server on `http://localhost:3000`:
|
### Toast UI Calendar
|
||||||
|
```
|
||||||
|
// ES MODULE
|
||||||
|
import Calendar from '@toast-ui/calendar';
|
||||||
|
|
||||||
```bash
|
// CSS 적용
|
||||||
# npm
|
import '@toast-ui/calendar/dist/toastui-calendar.min.css';
|
||||||
npm run dev
|
|
||||||
|
|
||||||
# pnpm
|
|
||||||
pnpm dev
|
|
||||||
|
|
||||||
# yarn
|
|
||||||
yarn dev
|
|
||||||
|
|
||||||
# bun
|
|
||||||
bun run dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Production
|
### Toast UI Grid
|
||||||
|
|
||||||
Build the application for production:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# npm
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# pnpm
|
|
||||||
pnpm build
|
|
||||||
|
|
||||||
# yarn
|
|
||||||
yarn build
|
|
||||||
|
|
||||||
# bun
|
|
||||||
bun run build
|
|
||||||
```
|
```
|
||||||
|
// ES MODULE
|
||||||
|
import 'tui-grid/dist/tui-grid.css';
|
||||||
|
import 'tui-date-picker/dist/tui-date-picker.min.css';
|
||||||
|
|
||||||
Locally preview production build:
|
// CSS 적용
|
||||||
|
import Grid from 'tui-grid';
|
||||||
```bash
|
|
||||||
# npm
|
|
||||||
npm run preview
|
|
||||||
|
|
||||||
# pnpm
|
|
||||||
pnpm preview
|
|
||||||
|
|
||||||
# yarn
|
|
||||||
yarn preview
|
|
||||||
|
|
||||||
# bun
|
|
||||||
bun run preview
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
|
||||||
|
|||||||
40
nuxt/components/common/DefaultSelectCode.vue
Normal file
40
nuxt/components/common/DefaultSelectCode.vue
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { GridCodeType } from '~/types';
|
||||||
|
|
||||||
|
const value = defineModel<string>({ default: '' });
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
options: GridCodeType[];
|
||||||
|
className?: string;
|
||||||
|
selectType?: 'SELECT' | 'ALL';
|
||||||
|
isLoading?: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const selectOptions = computed(() => {
|
||||||
|
if (props.selectType === 'REQUIRED') {
|
||||||
|
return [{ label: '선택', value: '' }, ...props.options];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.selectType === 'ALL') {
|
||||||
|
return [{ label: '전체', value: '' }, ...props.options];
|
||||||
|
}
|
||||||
|
|
||||||
|
return props.options;
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['change']);
|
||||||
|
|
||||||
|
const change = () => {
|
||||||
|
emit('change');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
:class="className"
|
||||||
|
:options="selectOptions"
|
||||||
|
:loading="isLoading"
|
||||||
|
v-model:value="value"
|
||||||
|
@change="change"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
29
nuxt/components/common/InstCodeSelect.vue
Normal file
29
nuxt/components/common/InstCodeSelect.vue
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps<{
|
||||||
|
className?: string;
|
||||||
|
selectType?: 'SELECT' | 'ALL';
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const commonCodeStore = useCommonCodeStore();
|
||||||
|
const value = defineModel<string>('');
|
||||||
|
|
||||||
|
const { data, isLoading } = useQuery({
|
||||||
|
queryKey: ['INST_CODE_LIST'],
|
||||||
|
queryFn: async () => {
|
||||||
|
return await commonCodeStore.searchInstCodeList();
|
||||||
|
},
|
||||||
|
staleTime: 60 * 1000,
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnMount: false
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<common-default-select-code
|
||||||
|
v-if="!isLoading"
|
||||||
|
:class-name="className"
|
||||||
|
:select-type="selectType"
|
||||||
|
:options="data"
|
||||||
|
v-model="value"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import 'tui-pagination/dist/tui-pagination.css';
|
|
||||||
import Pagination from 'tui-pagination/dist/tui-pagination';
|
|
||||||
import type { PaginationType } from '~/types/data/pagination';
|
|
||||||
|
|
||||||
const instance = ref();
|
|
||||||
const paginationRef = ref();
|
|
||||||
const props = defineProps<PaginationType>();
|
|
||||||
const emit = defineEmits(['change']);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
instance.value = new Pagination(paginationRef.value, {
|
|
||||||
totalItems: props.totalItems,
|
|
||||||
itemPerPage: props.itemsPerPage,
|
|
||||||
visiblePages: props.visiblePages ?? 10,
|
|
||||||
centerAlign: props.centerAlign ?? false,
|
|
||||||
usageStatistics: false
|
|
||||||
});
|
|
||||||
|
|
||||||
instance.value.on('beforeMove', (data: any) => {
|
|
||||||
emit('change', data.page);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props,
|
|
||||||
(newValue) => {
|
|
||||||
instance.value.setItemsPerPage(newValue.itemsPerPage);
|
|
||||||
instance.value.setTotalItems(newValue.itemsPerPage);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div ref="paginationRef" class="tui-pagination"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
163
nuxt/components/data/pagination.vue
Normal file
163
nuxt/components/data/pagination.vue
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import 'tui-pagination/dist/tui-pagination.css';
|
||||||
|
import type { PaginationType } from '~/types/data/pagination';
|
||||||
|
import {
|
||||||
|
DoubleLeftOutlined,
|
||||||
|
DoubleRightOutlined,
|
||||||
|
LeftOutlined,
|
||||||
|
RightOutlined
|
||||||
|
} from '@ant-design/icons-vue';
|
||||||
|
|
||||||
|
const props = defineProps<PaginationType>();
|
||||||
|
const emit = defineEmits(['change']);
|
||||||
|
|
||||||
|
const totalPages = computed(() => Math.ceil(props.totalElements / props.size));
|
||||||
|
const rangePages = computed(() =>
|
||||||
|
Array.from({ length: totalPages.value }, (_, i) => i + 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
const ranges = computed(() => {
|
||||||
|
const ranges: number[][] = [];
|
||||||
|
do {
|
||||||
|
ranges.push(rangePages.value.splice(0, props.showPaginationCount));
|
||||||
|
} while (rangePages.value.length !== 0);
|
||||||
|
|
||||||
|
if (ranges[0].length === 0) {
|
||||||
|
ranges[0][0] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ranges;
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentRange = computed(() => {
|
||||||
|
for (const range of ranges.value) {
|
||||||
|
if (range.some((i) => i === props.page)) {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentPeriod = computed(() => {
|
||||||
|
for (let i = 0; i < ranges.value.length; ++i) {
|
||||||
|
if (ranges.value[i].some((i) => i === props.page)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
const prevPageNumber = computed(() => {
|
||||||
|
const range = ranges.value[currentPeriod.value - 1];
|
||||||
|
if (range) {
|
||||||
|
return range[range.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return props.page;
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextPageNumber = computed(() => {
|
||||||
|
const range = ranges.value[currentPeriod.value + 1];
|
||||||
|
if (range) {
|
||||||
|
return range[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return props.page;
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstPage = () => {
|
||||||
|
submitPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const prevPage = () => {
|
||||||
|
submitPage(prevPageNumber.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const nextPage = () => {
|
||||||
|
submitPage(nextPageNumber.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const lastPage = () => {
|
||||||
|
submitPage(totalPages.value ? totalPages.value : 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const change = (value) => {
|
||||||
|
if (props.size !== value) {
|
||||||
|
emit('change', props.page, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const movePage = (value) => {
|
||||||
|
submitPage(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitPage = (page: number) => {
|
||||||
|
if (props.page !== page) {
|
||||||
|
emit('change', page, props.size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
{ label: '15', value: 15 },
|
||||||
|
{ label: '30', value: 30 },
|
||||||
|
{ label: '50', value: 50 },
|
||||||
|
{ label: '100', value: 100 }
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-row justify="space-between" class="mt-5">
|
||||||
|
<a-col>
|
||||||
|
<a-space>
|
||||||
|
<a-select :options="options" :value="size" @change="change" />
|
||||||
|
<span>건/페이지 (총 {{ totalElements }}건)</span>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
<a-col
|
||||||
|
><a-space>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
:icon="h(DoubleLeftOutlined)"
|
||||||
|
size="small"
|
||||||
|
class="pagination-icon-size text-black"
|
||||||
|
@click="firstPage"
|
||||||
|
/>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
:icon="h(LeftOutlined)"
|
||||||
|
class="pagination-icon-size text-black"
|
||||||
|
size="small"
|
||||||
|
@click="prevPage"
|
||||||
|
/>
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
size="small"
|
||||||
|
:type="pageNo === page ? 'default' : `link`"
|
||||||
|
class="text-black"
|
||||||
|
v-for="pageNo in currentRange"
|
||||||
|
:key="`pagination-${pageNo}`"
|
||||||
|
@click="() => movePage(pageNo)"
|
||||||
|
>{{ pageNo }}</a-button
|
||||||
|
>
|
||||||
|
</a-space>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
:icon="h(RightOutlined)"
|
||||||
|
size="small"
|
||||||
|
class="pagination-icon-size text-black"
|
||||||
|
@click="nextPage"
|
||||||
|
/>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
:icon="h(DoubleRightOutlined)"
|
||||||
|
class="pagination-icon-size text-black"
|
||||||
|
size="small"
|
||||||
|
@click="lastPage"
|
||||||
|
/>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
<a-col></a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
20
nuxt/constants/grid/index.ts
Normal file
20
nuxt/constants/grid/index.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export const BOOLEANS = [
|
||||||
|
{ text: '사용', value: 'true' },
|
||||||
|
{ text: '미사용', value: 'false' }
|
||||||
|
];
|
||||||
|
|
||||||
|
export const YES_OR_NO_CODE_LIST = [
|
||||||
|
{ text: '예', value: 'true' },
|
||||||
|
{ text: '아니오', value: 'false' }
|
||||||
|
];
|
||||||
|
|
||||||
|
export const LOCK_CODE_LIST = [
|
||||||
|
{ text: '정상', value: 'false' },
|
||||||
|
{ text: '잠김', value: 'true' }
|
||||||
|
];
|
||||||
|
|
||||||
|
export const ADMIN_STATUS_CODE_LIST = [
|
||||||
|
{ text: '미승인', value: 'NONE' },
|
||||||
|
{ text: '승인', value: 'APRV' },
|
||||||
|
{ text: '반려', value: 'RJCT' }
|
||||||
|
];
|
||||||
@@ -21,12 +21,6 @@ export default defineNuxtConfig({
|
|||||||
autoImport: true
|
autoImport: true
|
||||||
},
|
},
|
||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
// plugins: [
|
|
||||||
// '~/plugins/ant-design-vue.ts'
|
|
||||||
// ],
|
|
||||||
// css: [
|
|
||||||
// 'ant-design-vue/dist/reset.css'
|
|
||||||
// ],
|
|
||||||
modules: [
|
modules: [
|
||||||
'@pinia/nuxt',
|
'@pinia/nuxt',
|
||||||
'@unocss/nuxt',
|
'@unocss/nuxt',
|
||||||
@@ -35,11 +29,11 @@ export default defineNuxtConfig({
|
|||||||
],
|
],
|
||||||
vite: {
|
vite: {
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['tui-grid', '@ant-design', 'ant-design-vue']
|
include: ['tui-grid', 'ant-design-vue']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
alias: {},
|
alias: {},
|
||||||
experimental: {
|
experimental: {
|
||||||
payloadExtraction: false
|
payloadExtraction: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
126
nuxt/pages/admin/content/index.vue
Normal file
126
nuxt/pages/admin/content/index.vue
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useContentStore } from '~/stores/contents';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const contentId = route.query.contentId;
|
||||||
|
|
||||||
|
const editorRef = ref();
|
||||||
|
|
||||||
|
const contentStore = useContentStore();
|
||||||
|
const { contents, initialValue } = storeToRefs(contentStore);
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
if (contentId) {
|
||||||
|
contentStore.searchContents(Number(contentId));
|
||||||
|
} else {
|
||||||
|
contentStore.resetContents();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
contents.value.contents = editorRef.value.getValue();
|
||||||
|
|
||||||
|
contentStore
|
||||||
|
.updateContents()
|
||||||
|
.then(() => {
|
||||||
|
message.success('콘텐츠 정보가 저장이 되었습니다.');
|
||||||
|
moveList();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
message.error('콘텐츠 저장에 실패하였습니다.');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const moveList = () => {
|
||||||
|
router.push('/admin/content/list');
|
||||||
|
};
|
||||||
|
|
||||||
|
const nonValid = computed(() => {
|
||||||
|
return !contents.value.contentTitle;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<client-only>
|
||||||
|
<a-space direction="vertical" class="w-full">
|
||||||
|
<a-card>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-form-item
|
||||||
|
label="제목"
|
||||||
|
label-align="left"
|
||||||
|
:colon="false"
|
||||||
|
:label-col="{ span: 2 }"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
title="제목"
|
||||||
|
placeholder="콘텐츠 제목"
|
||||||
|
v-model:value="contents.contentTitle"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-form-item
|
||||||
|
label="기관"
|
||||||
|
label-align="left"
|
||||||
|
:colon="false"
|
||||||
|
:label-col="{ span: 2 }"
|
||||||
|
>
|
||||||
|
<common-inst-code-select v-model:value="contents.orgId" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-form-item
|
||||||
|
label="내용"
|
||||||
|
label-align="left"
|
||||||
|
:colon="false"
|
||||||
|
:label-col="{ span: 2 }"
|
||||||
|
:wrapper-col="{ span: 22 }"
|
||||||
|
>
|
||||||
|
<lazy-data-editor ref="editorRef" :initial-value="initialValue" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-form-item
|
||||||
|
label="사용여부"
|
||||||
|
label-align="left"
|
||||||
|
:colon="false"
|
||||||
|
:label-col="{ span: 2 }"
|
||||||
|
:wrapper-col="{ span: 22 }"
|
||||||
|
>
|
||||||
|
<a-switch v-model:checked="contents.useYn" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-flex justify="space-between">
|
||||||
|
<a-space>
|
||||||
|
<common-permit-button api="/api/admin/contents/updateContents">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="save"
|
||||||
|
:disabled="nonValid"
|
||||||
|
v-if="!contentId"
|
||||||
|
>저장</a-button
|
||||||
|
>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="save"
|
||||||
|
v-if="contentId != null"
|
||||||
|
>수정</a-button
|
||||||
|
>
|
||||||
|
</common-permit-button>
|
||||||
|
<a-button type="default" @click="moveList">목록</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-flex>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</a-space>
|
||||||
|
</client-only>
|
||||||
|
</template>
|
||||||
202
nuxt/pages/admin/content/list.vue
Normal file
202
nuxt/pages/admin/content/list.vue
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { OptColumn, OptRowHeader } from 'tui-grid/types/options';
|
||||||
|
import { useContentStore } from '~/stores/contents';
|
||||||
|
import type { ContentType } from '~/types/contents';
|
||||||
|
import { useCommonCodeStore } from '~/stores';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const instCodeList = await useCommonCodeStore().searchInstCodeList();
|
||||||
|
const contentStore = useContentStore();
|
||||||
|
const { contentsList, contentsQuery } = storeToRefs(contentStore);
|
||||||
|
const gridRef = ref();
|
||||||
|
|
||||||
|
const gridRowHeaders: OptRowHeader[] = ['checkbox', 'rowNum'];
|
||||||
|
|
||||||
|
const columns: OptColumn[] = [
|
||||||
|
{
|
||||||
|
name: 'contentId',
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'contentTitle',
|
||||||
|
header: '콘텐츠제목'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'orgId',
|
||||||
|
header: '관리기관',
|
||||||
|
width: 100,
|
||||||
|
disabled: true,
|
||||||
|
formatter: 'listItemText',
|
||||||
|
resizable: true,
|
||||||
|
editor: {
|
||||||
|
type: 'select',
|
||||||
|
options: {
|
||||||
|
listItems: instCodeList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'useYn',
|
||||||
|
header: '사용여부',
|
||||||
|
width: 80,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'frstRgtrId',
|
||||||
|
header: '작성자',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'frstRegDt',
|
||||||
|
header: '작성일',
|
||||||
|
width: 130
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'lastMdfrId',
|
||||||
|
header: '수정자',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'lastMdfcnDt',
|
||||||
|
header: '수정일',
|
||||||
|
width: 130
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const contentType = [
|
||||||
|
{ label: '전체', value: 'TOTAL' },
|
||||||
|
{ label: '제목', value: 'TITLE' },
|
||||||
|
{ label: '내용', value: 'CONTENT' }
|
||||||
|
];
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
contentStore.searchContentList();
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
// contentStore.resetContentListQuery();
|
||||||
|
});
|
||||||
|
|
||||||
|
const search = () => {
|
||||||
|
contentStore.searchContentList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const list = computed(() => {
|
||||||
|
return contentsList.value.content;
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(list, (newValue) => {
|
||||||
|
if (gridRef.value) {
|
||||||
|
gridRef.value.off('dblclick');
|
||||||
|
if (newValue.length > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
gridRef.value.on('dblclick', ({ instance, rowKey }) => {
|
||||||
|
const row = instance.getRow(rowKey);
|
||||||
|
editPage(row.contentId);
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteContentList = async () => {
|
||||||
|
const checkedRows = gridRef.value.getCheckedRows() as Array<ContentType>;
|
||||||
|
|
||||||
|
if (!checkedRows.length) {
|
||||||
|
message.warn('삭제할 콘텐츠가 없습니다.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Modal.confirm({
|
||||||
|
type: 'warning',
|
||||||
|
okText: '예',
|
||||||
|
cancelText: '아니오',
|
||||||
|
title: '컨텐츠 삭제',
|
||||||
|
content: '선택한 컨텐츠를 삭제하시겠습니까?',
|
||||||
|
onOk: async () => {
|
||||||
|
const createdRows = checkedRows.filter((row) => row.contentId);
|
||||||
|
await contentStore.deleteContents(createdRows);
|
||||||
|
await contentStore.searchContentList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const movePage = (page: number) => {
|
||||||
|
contentsQuery.value.page = page;
|
||||||
|
search();
|
||||||
|
};
|
||||||
|
|
||||||
|
const editPage = (contentId: any) => {
|
||||||
|
const query = typeof contentId === 'number' ? `?contentId=${contentId}` : '';
|
||||||
|
router.push(`/admin/content${query}`);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<client-only>
|
||||||
|
<a-space direction="vertical" class="w-full">
|
||||||
|
<a-card>
|
||||||
|
<a-row :gutter="[16, 8]">
|
||||||
|
<a-col>
|
||||||
|
<a-space>
|
||||||
|
<a-typography-text>관리기관</a-typography-text>
|
||||||
|
<lazy-common-inst-code-select
|
||||||
|
key="inst-code-select"
|
||||||
|
v-model="contentsQuery.orgId"
|
||||||
|
class-name="w-40"
|
||||||
|
select-type="ALL"
|
||||||
|
/>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col>
|
||||||
|
<a-space>
|
||||||
|
<a-typography-text>검색어</a-typography-text>
|
||||||
|
<a-select
|
||||||
|
title="컨텐츠 구분"
|
||||||
|
class="w-20"
|
||||||
|
v-model:value="contentsQuery.type"
|
||||||
|
:options="contentType"
|
||||||
|
/>
|
||||||
|
<a-input title="검색어" placeholder="Search" class="w-60"
|
||||||
|
v-model:value="contentsQuery.keyword" allow-clear/>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
<a-col>
|
||||||
|
<a-button type="primary" @click="search">검색</a-button>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<a-card>
|
||||||
|
<a-space direction="vertical" class="w-full">
|
||||||
|
<a-flex justify="space-between">
|
||||||
|
<!-- <common-permit-button api="/api/admin/contents/deleteContents">-->
|
||||||
|
<!-- <a-button type="primary" danger @click="deleteContentList"-->
|
||||||
|
<!-- >삭제-->
|
||||||
|
<!-- </a-button>-->
|
||||||
|
<!-- </common-permit-button>-->
|
||||||
|
<!-- <common-permit-button api="/api/admin/contents/updateContents">-->
|
||||||
|
<!-- <a-button type="primary" @click="editPage">추가</a-button>-->
|
||||||
|
<!-- </common-permit-button>-->
|
||||||
|
</a-flex>
|
||||||
|
<data-grid
|
||||||
|
:key="`board-content-grid-${Math.random()}`"
|
||||||
|
:row-headers="gridRowHeaders"
|
||||||
|
:data="contentsList.content"
|
||||||
|
:columns="columns"
|
||||||
|
ref="gridRef"
|
||||||
|
/>
|
||||||
|
<data-pagination
|
||||||
|
:key="`pagination-${Math.random()}`"
|
||||||
|
:total-elements="contentsList.totalElements"
|
||||||
|
:show-pagination-count="10"
|
||||||
|
:size="contentsQuery.size"
|
||||||
|
:page="contentsQuery.page"
|
||||||
|
@change="movePage"
|
||||||
|
/>
|
||||||
|
</a-space>
|
||||||
|
</a-card>
|
||||||
|
</a-space>
|
||||||
|
</client-only>
|
||||||
|
</template>
|
||||||
140
nuxt/stores/contents/index.ts
Normal file
140
nuxt/stores/contents/index.ts
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import type {
|
||||||
|
ContentListQueryType,
|
||||||
|
ContentListType,
|
||||||
|
ContentType
|
||||||
|
} from '~/types/contents';
|
||||||
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
import type { Page } from '~/types/common';
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useAxios } from '~/composables/useAxios';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
const DEFAULT_CONTENT_QUERY: ContentListQueryType = {
|
||||||
|
keyword: '',
|
||||||
|
orgId: '',
|
||||||
|
page: 1,
|
||||||
|
siteId: '',
|
||||||
|
size: 10,
|
||||||
|
type: 'TOTAL'
|
||||||
|
};
|
||||||
|
|
||||||
|
const DEFAULT_CONTENTS_LIST: Page<ContentListType> = {
|
||||||
|
content: [],
|
||||||
|
totalElements: 0,
|
||||||
|
totalPages: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
const DEFAULT_CONTENTS: ContentType = {
|
||||||
|
contentTitle: '',
|
||||||
|
contentPlain: '',
|
||||||
|
contents: '',
|
||||||
|
frstRegDt: '',
|
||||||
|
frstRgtrId: '',
|
||||||
|
lastMdfcnDt: '',
|
||||||
|
lastMdfrId: '',
|
||||||
|
orgId: '',
|
||||||
|
siteId: '',
|
||||||
|
useYn: true
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useContentStore = defineStore('useContentStore', () => {
|
||||||
|
const contentsQuery = ref<ContentListQueryType>(
|
||||||
|
cloneDeep(DEFAULT_CONTENT_QUERY)
|
||||||
|
);
|
||||||
|
|
||||||
|
const contentsList = ref<Page<ContentListType>>(
|
||||||
|
cloneDeep(DEFAULT_CONTENTS_LIST)
|
||||||
|
);
|
||||||
|
|
||||||
|
const contents = ref<ContentType>(cloneDeep(DEFAULT_CONTENTS));
|
||||||
|
const initialValue = ref<string>('');
|
||||||
|
|
||||||
|
const resetContentListQuery = () => {
|
||||||
|
contentsQuery.value = cloneDeep(DEFAULT_CONTENT_QUERY);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetContentList = () => {
|
||||||
|
contentsList.value = cloneDeep(DEFAULT_CONTENTS_LIST);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetContents = () => {
|
||||||
|
contents.value = cloneDeep(DEFAULT_CONTENTS);
|
||||||
|
initialValue.value = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const initContentsQuery = () => {
|
||||||
|
contentsQuery.value = cloneDeep(DEFAULT_CONTENT_QUERY);
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchContentList = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await useAxios().get(
|
||||||
|
'/api/admin/contents/contentsList',
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
...contentsQuery.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
contentsList.value = data;
|
||||||
|
} catch (e) {
|
||||||
|
message.error('사이트 리스트를 불러오는데 실패하였습니다.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchContents = async (contentId: number) => {
|
||||||
|
try {
|
||||||
|
const { data } = await useAxios().get('/api/admin/contents/detail', {
|
||||||
|
params: {
|
||||||
|
contentId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
contents.value = data;
|
||||||
|
initialValue.value = data.contents;
|
||||||
|
} catch (e) {
|
||||||
|
message.error('컨텐츠 정보를 불러오는데 실패하였습니다.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateContents = () => {
|
||||||
|
console.log(contents.value);
|
||||||
|
return useAxios().post(
|
||||||
|
'/api/admin/contents/updateContents',
|
||||||
|
contents.value
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteContents = async (data: ContentType[]) => {
|
||||||
|
try {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
data.forEach((item) => {
|
||||||
|
params.append('contentId', String(item.contentId));
|
||||||
|
});
|
||||||
|
|
||||||
|
await useAxios().post('/api/admin/contents/deleteContents', null, {
|
||||||
|
params
|
||||||
|
});
|
||||||
|
message.success('컨텐츠 정보가 삭제 되었습니다.');
|
||||||
|
} catch (e) {
|
||||||
|
message.error('컨텐츠 정보 삭제에 실패하였습니다.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
contentsQuery,
|
||||||
|
contentsList,
|
||||||
|
contents,
|
||||||
|
initialValue,
|
||||||
|
resetContentListQuery,
|
||||||
|
searchContentList,
|
||||||
|
searchContents,
|
||||||
|
resetContentList,
|
||||||
|
resetContents,
|
||||||
|
initContentsQuery,
|
||||||
|
deleteContents,
|
||||||
|
updateContents
|
||||||
|
};
|
||||||
|
});
|
||||||
80
nuxt/stores/index.ts
Normal file
80
nuxt/stores/index.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import type { SiteType } from '~/types/sys/site';
|
||||||
|
import type { GridCodeType } from '~/types';
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { useAxios } from '~/composables/useAxios';
|
||||||
|
|
||||||
|
export const useLoadingStore = defineStore('useLoadingStore', () => {
|
||||||
|
const loadCount = ref<number>(0);
|
||||||
|
|
||||||
|
const incrementLoadCount = () => {
|
||||||
|
loadCount.value++;
|
||||||
|
};
|
||||||
|
|
||||||
|
const decrementLoadCount = () => {
|
||||||
|
loadCount.value--;
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetLoadCount = () => {
|
||||||
|
loadCount.value = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isLoading = computed(() => {
|
||||||
|
return loadCount.value > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
isLoading,
|
||||||
|
resetLoadCount,
|
||||||
|
incrementLoadCount,
|
||||||
|
decrementLoadCount
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useDefaultStore = defineStore('useDefaultStore', () => {
|
||||||
|
const siteInfo = ref<SiteType>({
|
||||||
|
siteId: '',
|
||||||
|
siteName: '',
|
||||||
|
siteDescription: '',
|
||||||
|
siteDomain: '',
|
||||||
|
siteType: '',
|
||||||
|
sitePrefix: '',
|
||||||
|
siteLocale: '',
|
||||||
|
siteLogo: '',
|
||||||
|
bscUrl: '',
|
||||||
|
lgnUrl: '',
|
||||||
|
delYn: false,
|
||||||
|
useYn: true,
|
||||||
|
frstRgtrId: '',
|
||||||
|
frstRegDt: '',
|
||||||
|
lastMdfrId: '',
|
||||||
|
lastMdfcnDt: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const fetchSiteInfo = async () => {
|
||||||
|
const { data } = await useAxios().get<SiteType>('/api/admin/siteInfo');
|
||||||
|
siteInfo.value = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
return { siteInfo, fetchSiteInfo };
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useCommonCodeStore = defineStore('useCommonCodeStore', () => {
|
||||||
|
|
||||||
|
const searchSiteCodeList = async (): Promise<GridCodeType[]> => {
|
||||||
|
const { data } = await useAxios().get('/api/admin/code/siteList');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchInstCodeList = async (): Promise<GridCodeType[]> => {
|
||||||
|
const { data } = await useAxios().get<GridCodeType[]>(
|
||||||
|
'/api/admin/code/instList'
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
searchInstCodeList,
|
||||||
|
searchSiteCodeList
|
||||||
|
};
|
||||||
|
});
|
||||||
10
nuxt/types/common/index.ts
Normal file
10
nuxt/types/common/index.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export type Page<T> = {
|
||||||
|
content: T[];
|
||||||
|
totalElements: number;
|
||||||
|
totalPages: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PagingQuery = {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
};
|
||||||
32
nuxt/types/contents/index.ts
Normal file
32
nuxt/types/contents/index.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
export type ContentListQueryType = {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
siteId: string;
|
||||||
|
orgId: string;
|
||||||
|
keyword: string;
|
||||||
|
type: 'TOTAL' | 'TITLE' | 'CONTENT';
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ContentListType = {
|
||||||
|
contentId: number;
|
||||||
|
contentTitle: string;
|
||||||
|
useYn: boolean;
|
||||||
|
frstRgtrId: string;
|
||||||
|
frstRegDt: string;
|
||||||
|
lastMdfrId: string;
|
||||||
|
lastMdfcnDt: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ContentType = {
|
||||||
|
contentId?: number;
|
||||||
|
siteId: string;
|
||||||
|
orgId: string;
|
||||||
|
contentTitle: string;
|
||||||
|
contents: string;
|
||||||
|
contentPlain: string;
|
||||||
|
useYn: boolean;
|
||||||
|
frstRgtrId: string;
|
||||||
|
frstRegDt: string;
|
||||||
|
lastMdfrId: string;
|
||||||
|
lastMdfcnDt: string;
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export type PaginationType = {
|
export type PaginationType = {
|
||||||
totalItems: number;
|
page: number;
|
||||||
itemsPerPage: number;
|
size: number;
|
||||||
visiblePages: number;
|
totalElements: number;
|
||||||
centerAlign?: boolean;
|
showPaginationCount: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
20
nuxt/types/index.ts
Normal file
20
nuxt/types/index.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export type PagingQueryType = {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GridCodeType = {
|
||||||
|
label?: string;
|
||||||
|
text?: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FileInfoType = {
|
||||||
|
fileId: number;
|
||||||
|
fileOriginalName: string;
|
||||||
|
filePath: string;
|
||||||
|
fileMimeType: string;
|
||||||
|
fileSize: number;
|
||||||
|
fileAltText: string;
|
||||||
|
fileDownloadCount: number;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user