에이젼트 테스트 (전송사 에이젼트 테스트페이지) 및 공통코드 기능 진행중
This commit is contained in:
parent
3d417c7b09
commit
736b343b1f
@ -42,7 +42,6 @@ public abstract class AbstractAgentService<T, M> implements AgentService<T> {
|
||||
return new RestResponse(HttpStatus.OK, "데이터를 정상적으로 입력했습니다.", totalTime + "초");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResponse findByInsertCnt(T agentVO) {
|
||||
int count = countByCondition(agentVO);
|
||||
return new RestResponse(HttpStatus.OK, "", count);
|
||||
|
||||
@ -4,7 +4,6 @@ import com.itn.admin.cmn.msg.RestResponse;
|
||||
|
||||
public interface AgentService<T> {
|
||||
RestResponse send(T agentVO);
|
||||
RestResponse findByInsertCnt(T agentVO);
|
||||
|
||||
RestResponse findByLogMoveCntWhereMessage(T agentVO);
|
||||
|
||||
|
||||
@ -20,9 +20,10 @@ import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
@MapperScan(basePackages = {
|
||||
"com.itn.admin.itn.dict.mapper",
|
||||
"com.itn.admin.itn.mjon.spam.mapper",
|
||||
"com.itn.admin.itn.user.mapper"
|
||||
"com.itn.admin.itn.dict.mapper"
|
||||
,"com.itn.admin.itn.mjon.spam.mapper"
|
||||
,"com.itn.admin.itn.user.mapper"
|
||||
,"com.itn.admin.itn.code.mapper"
|
||||
}
|
||||
, sqlSessionFactoryRef = "factory")
|
||||
class MainDatabaseConfig {
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
package com.itn.admin.itn.code.mapper;
|
||||
import java.util.List;
|
||||
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface CodeDetailMapper {
|
||||
List<CodeDetailVO> findByGroupId(String codeGroupId);
|
||||
CodeDetailVO findById(String codeId);
|
||||
void insert(CodeDetailVO codeDetailVO);
|
||||
void update(CodeDetailVO codeDetailVO);
|
||||
void delete(String codeId);
|
||||
}
|
||||
15
src/main/java/com/itn/admin/itn/code/mapper/CodeMapper.java
Normal file
15
src/main/java/com/itn/admin/itn/code/mapper/CodeMapper.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.itn.admin.itn.code.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface CodeMapper {
|
||||
List<CodeVO> findAll();
|
||||
CodeVO findById(String codeGroupId);
|
||||
void insert(CodeVO codeVO);
|
||||
void update(CodeVO codeVO);
|
||||
void delete(String codeGroupId);
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.itn.admin.itn.code.mapper.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CodeDetailVO {
|
||||
private String codeId;
|
||||
private String codeGroupId;
|
||||
private String codeName;
|
||||
private String codeValue;
|
||||
private Integer sortOrder;
|
||||
private String useYn;
|
||||
private String frstRegisterId;
|
||||
private String frstRegistPnttm;
|
||||
private String lastUpdusrId;
|
||||
private String lastUpdtPnttm;
|
||||
|
||||
// getters and setters
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.itn.admin.itn.code.mapper.domain;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CodeVO {
|
||||
private String codeGroupId;
|
||||
private String codeGroupName;
|
||||
private String description;
|
||||
private String frstRegisterId;
|
||||
private String frstRegistPnttm;
|
||||
private String lastUpdusrId;
|
||||
private String lastUpdtPnttm;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.itn.admin.itn.code.server;
|
||||
|
||||
import com.itn.admin.cmn.msg.RestResponse;
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CodeDetailService {
|
||||
|
||||
|
||||
// 특정 코드 그룹의 모든 상세 코드를 가져오는 메서드
|
||||
List<CodeDetailVO> getDetailsByGroupId(String codeGroupId);
|
||||
|
||||
// 특정 코드 상세를 ID로 가져오는 메서드
|
||||
CodeDetailVO getCodeDetailById(String codeId);
|
||||
|
||||
// 코드 상세 추가 메서드
|
||||
RestResponse addCodeDetail(CodeDetailVO codeDetail);
|
||||
|
||||
// 코드 상세 수정 메서드
|
||||
void updateCodeDetail(CodeDetailVO codeDetail);
|
||||
|
||||
// 코드 상세 삭제 메서드
|
||||
void deleteCodeDetail(String codeId);
|
||||
}
|
||||
20
src/main/java/com/itn/admin/itn/code/server/CodeService.java
Normal file
20
src/main/java/com/itn/admin/itn/code/server/CodeService.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.itn.admin.itn.code.server;
|
||||
|
||||
import com.itn.admin.cmn.msg.RestResponse;
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeVO;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CodeService {
|
||||
|
||||
List<CodeVO> getAllCodeGroups();
|
||||
|
||||
CodeVO getCodeGroupById(String codeGroupId);
|
||||
|
||||
RestResponse addCodeGroup(CodeVO codeGroup);
|
||||
|
||||
void updateCodeGroup(CodeVO codeGroup);
|
||||
|
||||
void deleteCodeGroup(String codeGroupId);
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.itn.admin.itn.code.server.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.itn.admin.cmn.msg.RestResponse;
|
||||
import com.itn.admin.itn.code.mapper.CodeDetailMapper;
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||
import com.itn.admin.itn.code.server.CodeDetailService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CodeDetailServiceImpl implements CodeDetailService {
|
||||
|
||||
@Autowired
|
||||
private CodeDetailMapper codeDetailMapper;
|
||||
|
||||
@Override
|
||||
public List<CodeDetailVO> getDetailsByGroupId(String codeGroupId) {
|
||||
return codeDetailMapper.findByGroupId(codeGroupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeDetailVO getCodeDetailById(String codeId) {
|
||||
return codeDetailMapper.findById(codeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestResponse addCodeDetail(CodeDetailVO codeDetail) {
|
||||
codeDetailMapper.insert(codeDetail);
|
||||
return new RestResponse(HttpStatus.OK, "등록되었습니다", codeDetail.getCodeName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCodeDetail(CodeDetailVO codeDetail) {
|
||||
codeDetailMapper.update(codeDetail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCodeDetail(String codeId) {
|
||||
codeDetailMapper.delete(codeId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.itn.admin.itn.code.server.impl;
|
||||
import java.util.List;
|
||||
|
||||
import com.itn.admin.cmn.msg.RestResponse;
|
||||
import com.itn.admin.itn.code.mapper.CodeMapper;
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeVO;
|
||||
import com.itn.admin.itn.code.server.CodeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CodeServiceImpl implements CodeService {
|
||||
|
||||
@Autowired
|
||||
private CodeMapper codeMapper;
|
||||
|
||||
public List<CodeVO> getAllCodeGroups() {
|
||||
return codeMapper.findAll();
|
||||
}
|
||||
|
||||
public CodeVO getCodeGroupById(String codeGroupId) {
|
||||
return codeMapper.findById(codeGroupId);
|
||||
}
|
||||
|
||||
public RestResponse addCodeGroup(CodeVO codeVO) {
|
||||
codeMapper.insert(codeVO);
|
||||
return new RestResponse(HttpStatus.OK, "등록되었습니다.", codeVO.getCodeGroupId());
|
||||
}
|
||||
|
||||
public void updateCodeGroup(CodeVO codeVO) {
|
||||
codeMapper.update(codeVO);
|
||||
}
|
||||
|
||||
public void deleteCodeGroup(String codeGroupId) {
|
||||
codeMapper.delete(codeGroupId);
|
||||
}
|
||||
}
|
||||
26
src/main/java/com/itn/admin/itn/code/web/CodeController.java
Normal file
26
src/main/java/com/itn/admin/itn/code/web/CodeController.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.itn.admin.itn.code.web;
|
||||
|
||||
import com.itn.admin.itn.dict.service.DictionaryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class CodeController {
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
@Autowired
|
||||
public void setDictionaryService(DictionaryService dictionaryService) {
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/code/list")
|
||||
public String list() {
|
||||
return "itn/code/list";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.itn.admin.itn.code.web;
|
||||
|
||||
import com.itn.admin.cmn.msg.RestResponse;
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeDetailVO;
|
||||
import com.itn.admin.itn.code.server.CodeDetailService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/code-details") // URL 경로를 '/api/code-details'로 변경
|
||||
public class CodeDetailRestController {
|
||||
|
||||
@Autowired
|
||||
private CodeDetailService codeDetailService;
|
||||
|
||||
// 특정 코드 그룹의 모든 상세 코드 목록을 가져오는 메서드
|
||||
@GetMapping("/{codeGroupId}")
|
||||
public List<CodeDetailVO> getDetailsByGroupId(@PathVariable String codeGroupId) {
|
||||
return codeDetailService.getDetailsByGroupId(codeGroupId);
|
||||
}
|
||||
|
||||
// 특정 코드 상세를 ID로 가져오는 메서드
|
||||
@GetMapping("/detail/{codeId}")
|
||||
public CodeDetailVO getCodeDetailById(@PathVariable String codeId) {
|
||||
return codeDetailService.getCodeDetailById(codeId);
|
||||
}
|
||||
|
||||
// 코드 상세 추가 메서드
|
||||
@PostMapping
|
||||
public ResponseEntity<RestResponse> addCodeDetail(@RequestBody CodeDetailVO codeDetail) {
|
||||
return ResponseEntity.ok().body(codeDetailService.addCodeDetail(codeDetail));
|
||||
}
|
||||
|
||||
// 코드 상세 수정 메서드
|
||||
@PutMapping("/detail/{codeId}")
|
||||
public void updateCodeDetail(@PathVariable String codeId, @RequestBody CodeDetailVO codeDetail) {
|
||||
codeDetail.setCodeId(codeId);
|
||||
codeDetailService.updateCodeDetail(codeDetail);
|
||||
}
|
||||
|
||||
// 코드 상세 삭제 메서드
|
||||
@DeleteMapping("/detail/{codeId}")
|
||||
public void deleteCodeDetail(@PathVariable String codeId) {
|
||||
codeDetailService.deleteCodeDetail(codeId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.itn.admin.itn.code.web;
|
||||
|
||||
import com.itn.admin.cmn.msg.RestResponse;
|
||||
import com.itn.admin.itn.code.mapper.domain.CodeVO;
|
||||
import com.itn.admin.itn.code.server.CodeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/codes") // URL 경로를 '/api/codes'로 설정
|
||||
public class CodeRestController {
|
||||
|
||||
@Autowired
|
||||
private CodeService codeService;
|
||||
|
||||
// 코드 그룹 목록을 가져오는 메서드
|
||||
@GetMapping
|
||||
public List<CodeVO> getAllCodeGroups() {
|
||||
return codeService.getAllCodeGroups();
|
||||
}
|
||||
|
||||
// 특정 코드 그룹을 ID로 가져오는 메서드
|
||||
@GetMapping("/{codeGroupId}")
|
||||
public CodeVO getCodeGroupById(@PathVariable String codeGroupId) {
|
||||
return codeService.getCodeGroupById(codeGroupId);
|
||||
}
|
||||
|
||||
// 코드 그룹 추가 메서드
|
||||
@PostMapping
|
||||
public ResponseEntity<RestResponse> addCodeGroup(@RequestBody CodeVO codeGroup) {
|
||||
return ResponseEntity.ok().body(codeService.addCodeGroup(codeGroup));
|
||||
}
|
||||
|
||||
// 코드 그룹 수정 메서드
|
||||
@PutMapping("/{codeGroupId}")
|
||||
public void updateCodeGroup(@PathVariable String codeGroupId, @RequestBody CodeVO codeGroup) {
|
||||
codeGroup.setCodeGroupId(codeGroupId);
|
||||
codeService.updateCodeGroup(codeGroup);
|
||||
}
|
||||
|
||||
// 코드 그룹 삭제 메서드
|
||||
@DeleteMapping("/{codeGroupId}")
|
||||
public void deleteCodeGroup(@PathVariable String codeGroupId) {
|
||||
codeService.deleteCodeGroup(codeGroupId);
|
||||
}
|
||||
}
|
||||
@ -24,7 +24,7 @@ public class DictionaryController {
|
||||
//
|
||||
// model.addAttribute("list", resultMap.get("resultList"));
|
||||
|
||||
return "dict/list";
|
||||
return "itn/dict/list";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ public class UserController {
|
||||
model.addAttribute("list", resultMap.get("resultList"));
|
||||
model.addAttribute("roles", resultMap.get("roles"));
|
||||
|
||||
return "user/list";
|
||||
return "itn/user/list";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -69,7 +69,8 @@
|
||||
count(*) as cnt
|
||||
FROM
|
||||
MUNJAON_MSG_LOG
|
||||
WHERE SEND_STATUS = 1000
|
||||
WHERE 1=1
|
||||
-- and SEND_STATUS = 1000
|
||||
and MSG_TYPE = #{msgType}
|
||||
and MESSAGE LIKE CONCAT(#{message}, '%')
|
||||
</select>
|
||||
@ -81,8 +82,7 @@
|
||||
count(*) as cnt
|
||||
FROM
|
||||
MUNJAON_MSG_LOG
|
||||
WHERE SEND_STATUS = 1000
|
||||
and MSG_TYPE = #{msgType}
|
||||
WHERE MESSAGE LIKE CONCAT(#{message}, '%')
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
@ -65,19 +65,20 @@
|
||||
|
||||
<!-- 리포트할때 현재 데이터가 LOG 테이블에 이동됐는지 확인 -->
|
||||
<select id="countByLogMoveCntWhereMsgTypeAndMessage" resultType="Integer" parameterType="agentCTwoVO">
|
||||
/* one countByLogMoveCntWhereMsgTypeAndMessage */
|
||||
/* two countByLogMoveCntWhereMsgTypeAndMessage */
|
||||
SELECT
|
||||
count(*) as cnt
|
||||
FROM
|
||||
MUNJAON_MSG_LOG
|
||||
WHERE SEND_STATUS = 1000
|
||||
WHERE 1=1
|
||||
-- and SEND_STATUS = 1000
|
||||
and MSG_TYPE = #{msgType}
|
||||
and MESSAGE LIKE CONCAT(#{message}, '%')
|
||||
</select>
|
||||
|
||||
<!-- 리포트할때 전체 데이터가 LOG 테이블에 이동됐느지 확인 -->
|
||||
<select id="findAllLogMoveCnt" resultType="Integer" parameterType="agentCTwoVO">
|
||||
/* one findAllLogMoveCnt */
|
||||
/* two findAllLogMoveCnt */
|
||||
SELECT
|
||||
count(*) as cnt
|
||||
FROM
|
||||
|
||||
40
src/main/resources/mapper/itn/code/CodeDetailMapper.xml
Normal file
40
src/main/resources/mapper/itn/code/CodeDetailMapper.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.itn.admin.itn.code.mapper.CodeDetailMapper">
|
||||
|
||||
<!-- 특정 코드 그룹의 모든 상세 코드를 조회하는 쿼리 -->
|
||||
<select id="findByGroupId" parameterType="String" resultType="codeDetailVO">
|
||||
SELECT * FROM common_code_detail WHERE code_group_id = #{codeGroupId}
|
||||
</select>
|
||||
|
||||
<!-- 특정 코드 상세를 ID로 조회하는 쿼리 -->
|
||||
<select id="findById" parameterType="String" resultType="codeDetailVO">
|
||||
SELECT * FROM common_code_detail WHERE code_id = #{codeId}
|
||||
</select>
|
||||
|
||||
<!-- 코드 상세를 추가하는 쿼리 -->
|
||||
<insert id="insert" parameterType="codeDetailVO">
|
||||
INSERT INTO common_code_detail (code_id, code_group_id, code_name, code_value, sort_order, use_yn, frst_register_id, frst_regist_pnttm, last_updusr_id, last_updt_pnttm)
|
||||
VALUES (#{codeId}, #{codeGroupId}, #{codeName}, #{codeValue}, #{sortOrder}, #{useYn}, #{frstRegisterId}, #{frstRegistPnttm}, #{lastUpdusrId}, #{lastUpdtPnttm})
|
||||
</insert>
|
||||
|
||||
<!-- 코드 상세를 수정하는 쿼리 -->
|
||||
<update id="update" parameterType="codeDetailVO">
|
||||
UPDATE common_code_detail
|
||||
SET code_name = #{codeName},
|
||||
code_value = #{codeValue},
|
||||
sort_order = #{sortOrder},
|
||||
use_yn = #{useYn},
|
||||
last_updusr_id = #{lastUpdusrId},
|
||||
last_updt_pnttm = #{lastUpdtPnttm}
|
||||
WHERE code_id = #{codeId}
|
||||
</update>
|
||||
|
||||
<!-- 코드 상세를 삭제하는 쿼리 -->
|
||||
<delete id="delete" parameterType="String">
|
||||
DELETE FROM common_code_detail WHERE code_id = #{codeId}
|
||||
</delete>
|
||||
</mapper>
|
||||
38
src/main/resources/mapper/itn/code/CodeMapper.xml
Normal file
38
src/main/resources/mapper/itn/code/CodeMapper.xml
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.itn.admin.itn.code.mapper.CodeMapper">
|
||||
|
||||
<!-- 모든 코드 그룹을 조회하는 쿼리 -->
|
||||
<select id="findAll" resultType="codeVO">
|
||||
SELECT * FROM common_code
|
||||
</select>
|
||||
|
||||
<!-- 특정 코드 그룹을 ID로 조회하는 쿼리 -->
|
||||
<select id="findById" parameterType="String" resultType="codeVO">
|
||||
SELECT * FROM common_code WHERE code_group_id = #{codeGroupId}
|
||||
</select>
|
||||
|
||||
<!-- 코드 그룹을 추가하는 쿼리 -->
|
||||
<insert id="insert" parameterType="codeVO">
|
||||
INSERT INTO common_code (code_group_id, code_group_name, description, frst_register_id, frst_regist_pnttm, last_updusr_id, last_updt_pnttm)
|
||||
VALUES (#{codeGroupId}, #{codeGroupName}, #{description}, #{frstRegisterId}, #{frstRegistPnttm}, #{lastUpdusrId}, #{lastUpdtPnttm})
|
||||
</insert>
|
||||
|
||||
<!-- 코드 그룹을 수정하는 쿼리 -->
|
||||
<update id="update" parameterType="codeVO">
|
||||
UPDATE common_code
|
||||
SET code_group_name = #{codeGroupName},
|
||||
description = #{description},
|
||||
last_updusr_id = #{lastUpdusrId},
|
||||
last_updt_pnttm = #{lastUpdtPnttm}
|
||||
WHERE code_group_id = #{codeGroupId}
|
||||
</update>
|
||||
|
||||
<!-- 코드 그룹을 삭제하는 쿼리 -->
|
||||
<delete id="delete" parameterType="String">
|
||||
DELETE FROM common_code WHERE code_group_id = #{codeGroupId}
|
||||
</delete>
|
||||
</mapper>
|
||||
@ -22,6 +22,9 @@
|
||||
<typeAlias type="com.itn.admin.agent.client.two.mapper.domain.AgentCTwoVO" alias="agentCTwoVO"/>
|
||||
<typeAlias type="com.itn.admin.agent.server.mapper.domain.AgentSVO" alias="agentSVO"/>
|
||||
|
||||
<typeAlias type="com.itn.admin.itn.code.mapper.domain.CodeVO" alias="codeVO"/>
|
||||
<typeAlias type="com.itn.admin.itn.code.mapper.domain.CodeDetailVO" alias="codeDetailVO"/>
|
||||
|
||||
</typeAliases>
|
||||
|
||||
<!-- <environments default="development">-->
|
||||
|
||||
@ -19,8 +19,9 @@ function fn_oneInsertScriptStart(){
|
||||
}
|
||||
|
||||
|
||||
// LOG 테이블에
|
||||
function fn_oneReportScriptStart(){
|
||||
oneStartReportTimer($('#oneUserId').val()); // report 타임어택 시작
|
||||
oneStartReportTimer(); // report 타임어택 시작
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +65,9 @@ function fn_oneInsertCntAndTime(){
|
||||
|
||||
var jsonObject = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (!(value instanceof File)) {
|
||||
jsonObject[key] = value;
|
||||
}
|
||||
});
|
||||
console.log('url : /agent/one/findByInsertCnt');
|
||||
$.ajax({
|
||||
@ -88,6 +91,7 @@ function fn_oneInsertCntAndTime(){
|
||||
if(cnt >= numberOnly){
|
||||
oneStopInsertTimer();
|
||||
oneStartTransferTimer($('#oneUserId').val()); // 이관 카운트
|
||||
fn_oneReportScriptStart();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -190,7 +194,7 @@ function fn_oneTranferCntAndTime(userId){
|
||||
function oneStartReportTimer(userId) {
|
||||
console.log(' :: startReportTimer :: ');
|
||||
let startTime = Date.now();
|
||||
oneStartReporingCntTimer(userId);
|
||||
oneStartReporingCntTimer();
|
||||
oneIntervalId_reporingSeconds = setInterval(function() {
|
||||
let currentTime = Date.now();
|
||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
||||
@ -198,10 +202,10 @@ function oneStartReportTimer(userId) {
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function oneStartReporingCntTimer(userId) {
|
||||
function oneStartReporingCntTimer() {
|
||||
// 1초마다 fn_twoReportCntAndTime 함수를 호출
|
||||
oneReporingCntIntervalId = setInterval(function() {
|
||||
fn_oneReportCntAndTime(userId);
|
||||
fn_oneReportCntAndTime();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@ -212,7 +216,7 @@ function oneStopReporingTimer() {
|
||||
}
|
||||
|
||||
|
||||
function fn_oneReportCntAndTime(userId){
|
||||
function fn_oneReportCntAndTime(){
|
||||
|
||||
// 폼 데이터를 수집
|
||||
var formData = new FormData($("#divOneSms .sendForm")[0]);
|
||||
@ -225,7 +229,7 @@ function fn_oneReportCntAndTime(userId){
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/agent/one/findByInsertCnt",
|
||||
url: "/agent/one/findByLogMoveCntWhereMessage",
|
||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
|
||||
@ -19,8 +19,8 @@ function fn_twoInsertScriptStart(){
|
||||
}
|
||||
|
||||
|
||||
function fn_twoReportScriptStart(ajaxUrl){
|
||||
twoStartReportTimer($('#twoUserId').val(), ajaxUrl); // report 타임어택 시작
|
||||
function fn_twoReportScriptStart(){
|
||||
twoStartReportTimer(); // report 타임어택 시작
|
||||
}
|
||||
|
||||
|
||||
@ -89,6 +89,7 @@ function fn_twoInsertCntAndTime(){
|
||||
if(cnt >= numberOnly){
|
||||
twoStopInsertTimer();
|
||||
twoStartTransferTimer($('#twoUserId').val()); // 이관 카운트
|
||||
fn_twoReportScriptStart();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -142,13 +143,13 @@ function fn_twoTranferCntAndTime(userId){
|
||||
// 폼 데이터를 수집
|
||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
||||
|
||||
console.log('? :: ', formData);
|
||||
// console.log('? :: ', formData);
|
||||
var jsonObject = {};
|
||||
formData.forEach((value, key) => {
|
||||
jsonObject[key] = value;
|
||||
});
|
||||
jsonObject['userId'] = userId;
|
||||
console.log('jsonObject : ', jsonObject);
|
||||
// console.log('jsonObject : ', jsonObject);
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
@ -192,10 +193,10 @@ function fn_twoTranferCntAndTime(userId){
|
||||
// 리포트 영역
|
||||
// 리포트 영역
|
||||
// 리포트 영역
|
||||
function twoStartReportTimer(userId, ajaxUrl) {
|
||||
console.log(' :: startReportTimer :: ');
|
||||
function twoStartReportTimer() {
|
||||
// console.log(' :: startReportTimer :: ');
|
||||
let startTime = Date.now();
|
||||
twoStartReporingCntTimer(userId, ajaxUrl);
|
||||
twoStartReporingCntTimer();
|
||||
twoIntervalId_reporingSeconds = setInterval(function() {
|
||||
let currentTime = Date.now();
|
||||
let elapsedTime = (currentTime - startTime) / 1000; // 밀리초를 초 단위로 변환
|
||||
@ -203,10 +204,10 @@ function twoStartReportTimer(userId, ajaxUrl) {
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function twoStartReporingCntTimer(userId, ajaxUrl) {
|
||||
function twoStartReporingCntTimer() {
|
||||
// 1초마다 fn_twoReportCntAndTime 함수를 호출
|
||||
twoReporingCntIntervalId = setInterval(function() {
|
||||
fn_twoReportCntAndTime(userId, ajaxUrl);
|
||||
fn_twoReportCntAndTime();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@ -217,27 +218,29 @@ function twoStopReporingTimer() {
|
||||
}
|
||||
|
||||
|
||||
function fn_twoReportCntAndTime(userId, ajaxUrl){
|
||||
function fn_twoReportCntAndTime(userId){
|
||||
|
||||
// 폼 데이터를 수집
|
||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
||||
|
||||
var jsonObject = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (!(value instanceof File)) {
|
||||
jsonObject[key] = value;
|
||||
}
|
||||
});
|
||||
jsonObject['userId'] = userId;
|
||||
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxUrl,
|
||||
url: "/agent/two/findByLogMoveCntWhereMessage",
|
||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
// async: true,
|
||||
success: function (data) {
|
||||
// console.log('tranfer data : ', data);
|
||||
console.log('tranfer data : ', data);
|
||||
|
||||
if (data.status == 'OK') {
|
||||
var cnt = data.data;
|
||||
@ -245,12 +248,12 @@ function fn_twoReportCntAndTime(userId, ajaxUrl){
|
||||
// 리포트 영역에 cnt 추가
|
||||
$('#divTwoSmsCard .reportSndCnt').text(cnt);
|
||||
// server DB에 update한 건수와 cnt비교
|
||||
var reportStartCnt = $('#divTwoSmsCard .reportStartCnt').text();
|
||||
var transferCnt = $('#divTwoSmsCard .insertCnt').text();
|
||||
|
||||
console.log('cnt : ', cnt);
|
||||
console.log('reportStartCnt : ', reportStartCnt);
|
||||
console.log('reportStartCnt : ', transferCnt);
|
||||
console.log('');
|
||||
if(cnt >= Number(reportStartCnt)){
|
||||
if(cnt >= Number(transferCnt)){
|
||||
twoStopReporingTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,7 +447,7 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row"><!-- 클라이언트 insert -->
|
||||
<div class="col-md-3 col-sm-6 col-12">
|
||||
<div class="col-md-4 col-sm-6 col-12">
|
||||
<div class="info-box bg-light">
|
||||
<span class="info-box-icon bg-gray" style="width: 35px;"><i class="fas fa-upload"></i></span>
|
||||
<div class="info-box-content">
|
||||
@ -485,15 +485,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 클라이언트 report -->
|
||||
<div class="col-md-5 col-sm-6 col-12">
|
||||
<div class="col-md-4 col-sm-6 col-12">
|
||||
<div class="info-box bg-light">
|
||||
<span class="info-box-icon bg-gray" style="width: 35px;"><i class="fas fa-chart-line"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">클라이언트 report (S -> C)</span>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="info-box-number reportStartCnt">0</span><span class="reportStartSubCnt"></span>
|
||||
<span class="info-box-number mx-2">→</span>
|
||||
<span class="info-box-number reportSndCnt">0</span>
|
||||
<span class="info-box-number reportStartCnt">0</span><!--<span class="reportStartSubCnt"></span>-->
|
||||
<!-- <span class="info-box-number mx-2">→</span>-->
|
||||
<!-- <span class="info-box-number reportSndCnt">0</span>-->
|
||||
<span class="info-box-unit font-weight-bold ml-2">건수</span>
|
||||
</div>
|
||||
<div class="progress">
|
||||
@ -509,18 +509,18 @@
|
||||
|
||||
</div>
|
||||
<!-- Reporting start 버튼 -->
|
||||
<div class="row">
|
||||
<!-- <div class="row">-->
|
||||
|
||||
<div class="col-12 text-left">
|
||||
<button class="btn btn-success rprtCrrntStrtBtn" data-tagid="oneUserId">
|
||||
<i class="fas fa-chart-line"></i> Report Current Data
|
||||
</button>
|
||||
<button class="btn btn-danger rprtAllStrtBtn" data-tagid="oneUserId">
|
||||
<i class="fas fa-chart-line"></i> Report All Data
|
||||
</button>
|
||||
</div>
|
||||
<!-- <div class="col-12 text-left">-->
|
||||
<!-- <button class="btn btn-success rprtCrrntStrtBtn" data-tagid="oneUserId">-->
|
||||
<!-- <i class="fas fa-chart-line"></i> Report Current Data-->
|
||||
<!-- </button>-->
|
||||
<!-- <button class="btn btn-danger rprtAllStrtBtn" data-tagid="oneUserId">-->
|
||||
<!-- <i class="fas fa-chart-line"></i> Report All Data-->
|
||||
<!-- </button>-->
|
||||
<!-- </div>-->
|
||||
|
||||
</div>
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -536,7 +536,7 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row"><!-- 클라이언트 insert -->
|
||||
<div class="col-md-3 col-sm-6 col-12">
|
||||
<div class="col-md-4 col-sm-6 col-12">
|
||||
<div class="info-box bg-light">
|
||||
<span class="info-box-icon bg-gray" style="width: 35px;"><i class="fas fa-upload"></i></span>
|
||||
<div class="info-box-content">
|
||||
@ -574,15 +574,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 클라이언트 report -->
|
||||
<div class="col-md-5 col-sm-6 col-12">
|
||||
<div class="col-md-4 col-sm-6 col-12">
|
||||
<div class="info-box bg-light">
|
||||
<span class="info-box-icon bg-gray" style="width: 35px;"><i class="fas fa-chart-line"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">클라이언트 report (S -> C)</span>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="info-box-number reportStartCnt">0</span><span class="reportStartSubCnt"></span>
|
||||
<span class="info-box-number mx-2">→</span>
|
||||
<span class="info-box-number reportSndCnt">0</span>
|
||||
<span class="info-box-number reportStartCnt">0</span><!--<span class="reportStartSubCnt"></span>-->
|
||||
<!-- <span class="info-box-number mx-2">→</span>-->
|
||||
<!-- <span class="info-box-number reportSndCnt">0</span>-->
|
||||
<span class="info-box-unit font-weight-bold ml-2">건수</span>
|
||||
</div>
|
||||
<div class="progress">
|
||||
@ -598,18 +598,18 @@
|
||||
|
||||
</div>
|
||||
<!-- Reporting start 버튼 -->
|
||||
<div class="row">
|
||||
<div class="col-12 text-left">
|
||||
<!-- <button class="btn btn-success newButtonClass">Now data report start</button> <!– 새로운 버튼 추가 –>-->
|
||||
<!-- <button class="btn btn-danger rprtAllStrtBtn" data-tagid="twoUserId">ALL data Reporting start</button>-->
|
||||
<button class="btn btn-success rprtCrrntStrtBtn" data-tagid="twoUserId">
|
||||
<i class="fas fa-chart-line"></i> Report Current Data
|
||||
</button>
|
||||
<button class="btn btn-danger rprtAllStrtBtn" data-tagid="twoUserId">
|
||||
<i class="fas fa-chart-line"></i> Report All Data
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="row">-->
|
||||
<!-- <div class="col-12 text-left">-->
|
||||
<!--<!– <button class="btn btn-success newButtonClass">Now data report start</button> <!– 새로운 버튼 추가 –>–>-->
|
||||
<!--<!– <button class="btn btn-danger rprtAllStrtBtn" data-tagid="twoUserId">ALL data Reporting start</button>–>-->
|
||||
<!-- <button class="btn btn-success rprtCrrntStrtBtn" data-tagid="twoUserId">-->
|
||||
<!-- <i class="fas fa-chart-line"></i> Report Current Data-->
|
||||
<!-- </button>-->
|
||||
<!-- <button class="btn btn-danger rprtAllStrtBtn" data-tagid="twoUserId">-->
|
||||
<!-- <i class="fas fa-chart-line"></i> Report All Data-->
|
||||
<!-- </button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -741,135 +741,6 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* client_1 reporting 버튼
|
||||
* */
|
||||
$("#divOneSmsCard .rprtAllStrtBtn").on("click", function () {
|
||||
|
||||
var ajaxUrl = '/agent/one/findByLogMoveCnt'
|
||||
// 폼 데이터를 수집
|
||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
||||
|
||||
var jsonObject = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (!(value instanceof File)) {
|
||||
jsonObject[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
var usertagId = '#'+$(this).data('tagid');
|
||||
jsonObject['userId'] = $(usertagId).val();
|
||||
|
||||
console.log('jsonObject : ', jsonObject);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/agent/server/allReport",
|
||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
// async: true,
|
||||
success: function (data) {
|
||||
// console.log('data : ', data);
|
||||
|
||||
if (data.status === 'OK') {
|
||||
if(data.data < 1){
|
||||
alert('리포팅할 데이터가 없습니다.');
|
||||
oneStopInsertTimer();
|
||||
return false;
|
||||
}
|
||||
|
||||
$("#divTwoSmsCard .reportStartCnt").text(data.data);
|
||||
fn_successAlert(data.data+'건', data.msg);
|
||||
}
|
||||
else {
|
||||
alert("오류 알림 : :: "+data.msg);
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
alert("저장에 실패하였습니다.");
|
||||
console.log("ERROR : " + JSON.stringify(e));
|
||||
},
|
||||
beforeSend : function(xmlHttpRequest, data) {
|
||||
if(data.data > 0){
|
||||
return false;
|
||||
}
|
||||
// 건수를 현황확인으로 이동
|
||||
fn_oneReportScriptStart();
|
||||
|
||||
},
|
||||
complete : function(xhr, textStatus) {
|
||||
oneStopInsertTimer();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* client_1 reporting 버튼
|
||||
* */
|
||||
$("#divOneSmsCard .rprtCrrntStrtBtn").on("click", function () {
|
||||
|
||||
var ajaxUrl = '/agent/one/findByLogMoveCntWhereMessage'
|
||||
|
||||
// 폼 데이터를 수집
|
||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
||||
|
||||
var jsonObject = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (!(value instanceof File)) {
|
||||
jsonObject[key] = value;
|
||||
}
|
||||
});
|
||||
var usertagId = '#'+$(this).data('tagid');
|
||||
jsonObject['userId'] = $(usertagId).val();
|
||||
|
||||
// console.log('two rprtCrrntStrtBtn jsonObject : ', jsonObject);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/agent/server/nowDataReport",
|
||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
// async: true,
|
||||
success: function (data) {
|
||||
// console.log('two rprtCrrntStrtBtn data : ', data);
|
||||
|
||||
if (data.status === 'OK') {
|
||||
if(data.data < 1){
|
||||
alert('리포팅할 데이터가 없습니다.');
|
||||
oneStopInsertTimer();
|
||||
return false;
|
||||
}
|
||||
var $oriTag = $("#divOneSmsCard .reportStartCnt");
|
||||
var oriText = $oriTag.text();
|
||||
var dataCnt = data.data;
|
||||
var totalCnt = dataCnt;
|
||||
if(Number(oriText) > 0){
|
||||
totalCnt = dataCnt + Number(oriText);
|
||||
$("#divOneSmsCard .reportStartSubCnt").text(' (+'+dataCnt+')');
|
||||
}
|
||||
$oriTag.text(totalCnt);
|
||||
fn_successAlert(data.data+'건', data.msg);
|
||||
}
|
||||
else {
|
||||
alert("오류 알림 : :: "+data.msg);
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
alert("저장에 실패하였습니다.");
|
||||
console.log("ERROR : " + JSON.stringify(e));
|
||||
},
|
||||
beforeSend : function(data) {
|
||||
if(data.data > 0){
|
||||
return false;
|
||||
}
|
||||
fn_oneReportScriptStart(ajaxUrl);
|
||||
|
||||
},
|
||||
complete : function(xhr, textStatus) {
|
||||
oneStopInsertTimer();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// client_2 영역
|
||||
// client_2 영역
|
||||
@ -970,148 +841,8 @@
|
||||
});
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* client_2 reporting 버튼
|
||||
* */
|
||||
$("#divTwoSmsCard .rprtAllStrtBtn").on("click", function () {
|
||||
|
||||
var ajaxUrl = '/agent/two/findByLogMoveCnt'
|
||||
// 폼 데이터를 수집
|
||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
||||
|
||||
var jsonObject = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (!(value instanceof File)) {
|
||||
jsonObject[key] = value;
|
||||
}
|
||||
});
|
||||
var usertagId = '#'+$(this).data('tagid');
|
||||
jsonObject['userId'] = $(usertagId).val();
|
||||
|
||||
console.log('jsonObject : ', jsonObject);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/agent/server/allReport",
|
||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
// async: true,
|
||||
success: function (data) {
|
||||
// console.log('data : ', data);
|
||||
|
||||
if (data.status === 'OK') {
|
||||
if(data.data < 1){
|
||||
alert('리포팅할 데이터가 없습니다.');
|
||||
oneStopInsertTimer();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$("#divTwoSmsCard .reportStartCnt").text(data.data);
|
||||
fn_successAlert(data.data+'건', data.msg);
|
||||
}
|
||||
else {
|
||||
alert("오류 알림 : :: "+data.msg);
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
alert("저장에 실패하였습니다.");
|
||||
console.log("ERROR : " + JSON.stringify(e));
|
||||
},
|
||||
beforeSend : function(xmlHttpRequest, data) {
|
||||
if(data.data > 0){
|
||||
return false;
|
||||
}
|
||||
fn_twoReportScriptStart(ajaxUrl);
|
||||
|
||||
},
|
||||
complete : function(xhr, textStatus) {
|
||||
oneStopInsertTimer();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* client_2 reporting 버튼
|
||||
* */
|
||||
$("#divTwoSmsCard .rprtCrrntStrtBtn").on("click", function () {
|
||||
|
||||
var ajaxUrl = '/agent/two/findByLogMoveCntWhereMessage'
|
||||
|
||||
// 폼 데이터를 수집
|
||||
var formData = new FormData($("#divTwoSms .sendForm")[0]);
|
||||
|
||||
var jsonObject = {};
|
||||
formData.forEach((value, key) => {
|
||||
if (!(value instanceof File)) {
|
||||
jsonObject[key] = value;
|
||||
}
|
||||
});
|
||||
var usertagId = '#'+$(this).data('tagid');
|
||||
jsonObject['userId'] = $(usertagId).val();
|
||||
|
||||
// console.log('two rprtCrrntStrtBtn jsonObject : ', jsonObject);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/agent/server/nowDataReport",
|
||||
data: JSON.stringify(jsonObject), // JSON 문자열로 변환된 데이터를 전송
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
// async: true,
|
||||
success: function (data) {
|
||||
// console.log('two rprtCrrntStrtBtn data : ', data);
|
||||
|
||||
if (data.status === 'OK') {
|
||||
if(data.data < 1){
|
||||
alert('리포팅할 데이터가 없습니다.');
|
||||
twoStopInsertTimer();
|
||||
return false;
|
||||
}
|
||||
var $oriTag = $("#divTwoSmsCard .reportStartCnt");
|
||||
var oriText = $oriTag.text();
|
||||
var dataCnt = data.data;
|
||||
var totalCnt = dataCnt;
|
||||
if(Number(oriText) > 0){
|
||||
totalCnt = dataCnt + Number(oriText);
|
||||
$("#divTwoSmsCard .reportStartSubCnt").text(' (+'+dataCnt+')');
|
||||
}
|
||||
$oriTag.text(totalCnt);
|
||||
fn_successAlert(data.data+'건', data.msg);
|
||||
}
|
||||
else {
|
||||
alert("오류 알림 : :: "+data.msg);
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
alert("저장에 실패하였습니다.");
|
||||
console.log("ERROR : " + JSON.stringify(e));
|
||||
},
|
||||
beforeSend : function(data) {
|
||||
if(data.data > 0){
|
||||
return false;
|
||||
}
|
||||
fn_twoReportScriptStart(ajaxUrl);
|
||||
|
||||
},
|
||||
complete : function(xhr, textStatus) {
|
||||
twoStopInsertTimer();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function fn_successAlert(title, msg){
|
||||
$(document).Toasts('create', {
|
||||
class: 'bg-info',
|
||||
title: title,
|
||||
subtitle: '',
|
||||
autohide : true,
|
||||
delay: 6000,
|
||||
body: msg
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@ -10,6 +10,9 @@
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" th:href="@{/plugins/fontawesome-free/css/all.min.css}">
|
||||
<!-- <link rel="stylesheet" th:href="@{/css/fontawesome/all.min.css}">-->
|
||||
|
||||
|
||||
|
||||
<!-- Ionicons -->
|
||||
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
|
||||
<!-- Ion Slider -->
|
||||
@ -32,6 +35,8 @@
|
||||
<!-- summernote -->
|
||||
<link rel="stylesheet" th:href="@{/plugins/summernote/summernote-bs4.min.css}">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" th:href="@{/plugins/toastr/toastr.min.css}">
|
||||
|
||||
|
||||
|
||||
@ -71,6 +76,8 @@
|
||||
<script th:src="@{/dist/js/pages/dashboard.js}"></script>
|
||||
<!-- <script th:src="@{/js/fontawesome/all.min.js}"></script>-->
|
||||
|
||||
<script th:src="@{/plugins/toastr/toastr.min.js}"></script>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
@ -91,6 +98,30 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function fn_successAlert(title, msg){
|
||||
$(document).Toasts('create', {
|
||||
class: 'bg-info',
|
||||
title: title,
|
||||
subtitle: '',
|
||||
autohide : true,
|
||||
delay: 6000,
|
||||
body: msg
|
||||
})
|
||||
}
|
||||
|
||||
function fn_failedAlert(title, msg){
|
||||
$(document).Toasts('create', {
|
||||
class: 'bg-danger',
|
||||
title: title,
|
||||
subtitle: '',
|
||||
autohide : true,
|
||||
delay: 3000,
|
||||
body: msg
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
@ -65,6 +65,14 @@
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav nav-treeview">
|
||||
<li class="nav-item">
|
||||
<a th:href="@{/code/list}" class="nav-link">
|
||||
<i class="nav-icon fas fa-code"></i>
|
||||
<p>공통코드</p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a th:href="@{/dict/list}" class="nav-link">
|
||||
|
||||
392
src/main/resources/templates/itn/code/list.html
Normal file
392
src/main/resources/templates/itn/code/list.html
Normal file
@ -0,0 +1,392 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="layout">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>공통코드 관리</title>
|
||||
<!-- 필요하다면 개별 파일에 사용될 css/js 선언 -->
|
||||
<style>
|
||||
/* 테이블 스타일 */
|
||||
.btn {
|
||||
padding: 5px 10px; /* 버튼 크기 조정 */
|
||||
}
|
||||
/* 타이틀과 버튼 가운데 정렬 */
|
||||
#commonCodeTable th {
|
||||
flex-grow: 1;
|
||||
text-align: center; /* 타이틀 텍스트 가운데 정렬 */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body layout:fragment="body">
|
||||
<div class="wrapper">
|
||||
<div th:replace="~{fragments/top_nav :: topFragment}"></div>
|
||||
|
||||
<!-- Main Sidebar Container -->
|
||||
<aside class="main-sidebar sidebar-dark-primary elevation-4" th:insert="~{fragments/mainsidebar :: sidebarFragment}"></aside>
|
||||
|
||||
<!-- Content Wrapper. Contains page content -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content Header (Page header) -->
|
||||
<div class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1 class="m-0">공통코드</h1>
|
||||
</div><!-- /.col -->
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active">관리</li>
|
||||
<li class="breadcrumb-item active">공통코드</li>
|
||||
</ol>
|
||||
</div><!-- /.col -->
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</div>
|
||||
<!-- /.content-header -->
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">목록 - 클릭하면 수정 가능합니다.</h3>
|
||||
<button class="btn btn-success float-right" data-toggle="modal" data-target="#addCodeGroupModal">추가</button>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<div class="card-body">
|
||||
<!-- 공통 코드 그룹 테이블 -->
|
||||
<table id="commonCodeTable" class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style=" width: 70px;">코드 그룹 ID</th>
|
||||
<th style=" width: 70px;">코드 그룹 이름</th>
|
||||
<th style=" width: 150px;">설명</th>
|
||||
<th style=" width: 10px;">상세 보기</th>
|
||||
<th style=" width: 10px;">수정</th>
|
||||
<th style=" width: 10px;">삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="commonCodeTableBody">
|
||||
<!-- 공통 코드 데이터가 동적으로 삽입될 자리 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
<!-- /Main content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
<!-- 공통 코드 그룹 추가 모달 -->
|
||||
<div class="modal fade" id="addCodeGroupModal" tabindex="-1" role="dialog" aria-labelledby="addCodeGroupModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addCodeGroupModalLabel">공통 코드 추가</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="addCodeGroupForm">
|
||||
<div class="form-group">
|
||||
<label for="codeGroupId">코드 그룹 ID</label>
|
||||
<input type="text" class="form-control" id="codeGroupId" name="codeGroupId" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="codeGroupName">코드 그룹 이름</label>
|
||||
<input type="text" class="form-control" id="codeGroupName" name="codeGroupName" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">설명</label>
|
||||
<textarea class="form-control" id="description" name="description"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
|
||||
<button type="button" class="btn btn-primary" onclick="addCodeGroup()">추가</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 공통 코드 상세 모달 -->
|
||||
<div class="modal fade" id="commonCodeDetailModal" tabindex="-1" role="dialog" aria-labelledby="commonCodeDetailModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="commonCodeDetailModalLabel">공통코드 상세</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>코드 ID</th>
|
||||
<th>코드 이름</th>
|
||||
<th>코드 값</th>
|
||||
<th>정렬 순서</th>
|
||||
<th>사용 여부</th>
|
||||
<th>수정</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="detailTableBody">
|
||||
<!-- 공통 코드 상세 데이터가 동적으로 삽입될 자리 -->
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- 추가 버튼을 모달 내부에 추가하여 코드 상세 추가를 트리거 -->
|
||||
<button class="btn btn-success float-right" onclick="showAddCodeDetailModal()">추가</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 공통 코드 상세 추가 모달 -->
|
||||
<div class="modal fade" id="addCodeDetailModal" tabindex="-1" role="dialog" aria-labelledby="addCodeDetailModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addCodeDetailModalLabel">공통 코드 상세 추가</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="addCodeDetailForm">
|
||||
<div class="form-group">
|
||||
<label for="detailCodeId">코드 ID</label>
|
||||
<input type="text" class="form-control" id="detailCodeId" name="codeId" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="detailCodeGroupId">코드 그룹 ID</label>
|
||||
<input type="text" class="form-control" id="detailCodeGroupId" name="codeGroupId" required readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="detailCodeName">코드 이름</label>
|
||||
<input type="text" class="form-control" id="detailCodeName" name="codeName" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="detailCodeValue">코드 값</label>
|
||||
<input type="text" class="form-control" id="detailCodeValue" name="codeValue" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="detailSortOrder">정렬 순서</label>
|
||||
<input type="number" class="form-control" id="detailSortOrder" name="sortOrder">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="detailUseYn">사용 여부</label>
|
||||
<select class="form-control" id="detailUseYn" name="useYn">
|
||||
<option value="Y">Yes</option>
|
||||
<option value="N">No</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
|
||||
<button type="button" class="btn btn-primary" onclick="addCommonCodeDetail()">추가</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="main-footer" th:insert="~{fragments/footer :: footerFragment}"></footer>
|
||||
|
||||
<!-- Control Sidebar -->
|
||||
<aside class="control-sidebar control-sidebar-dark">
|
||||
<!-- Control sidebar content goes here -->
|
||||
</aside>
|
||||
<!-- /.control-sidebar -->
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// 페이지 로드 시 코드 데이터를 가져오는 AJAX 호출
|
||||
loadCodes();
|
||||
|
||||
// 코드 그룹 목록을 불러오는 함수
|
||||
function loadCodes() {
|
||||
$.ajax({
|
||||
url: '/api/codes', // 변경된 URL
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
console.log('codes : ', data);
|
||||
let tableBody = $('#commonCodeTableBody');
|
||||
tableBody.empty(); // 기존 테이블 데이터 삭제
|
||||
data.forEach(function(code) {
|
||||
tableBody.append('<tr>' +
|
||||
'<td>' + code.codeGroupId + '</td>' +
|
||||
'<td>' + code.codeGroupName + '</td>' +
|
||||
'<td>' + code.description + '</td>' +
|
||||
'<td class="text-center"><button class="btn btn-info btn-sm" onclick="showDetails(\'' + code.codeGroupId + '\')">상세 보기</button></td>' +
|
||||
'<td class="text-center"><button class="btn btn-primary btn-sm" onclick="editCodeGroup(\'' + code.codeGroupId + '\')">수정</button></td>' +
|
||||
'<td class="text-center"><button class="btn btn-danger btn-sm" onclick="deleteCodeGroup(\'' + code.codeGroupId + '\')">삭제</button></td>' +
|
||||
'</tr>');
|
||||
});
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('코드 데이터를 불러오는 데 실패했습니다.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 코드 그룹 추가 함수
|
||||
window.addCodeGroup = function() { // 폼 데이터를 배열 형태로 직렬화
|
||||
var formDataArray = $("#addCodeGroupForm").serializeArray();
|
||||
var formData = {};
|
||||
|
||||
// 배열 데이터를 JSON 객체로 변환
|
||||
$.each(formDataArray, function(_, field) {
|
||||
formData[field.name] = field.value;
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: '/api/codes', // 변경된 URL
|
||||
type: 'POST',
|
||||
data: JSON.stringify(formData),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
success: function(data) {
|
||||
$('#addCodeGroupModal').modal('hide');
|
||||
loadCodes(); // 테이블 갱신
|
||||
fn_successAlert("성공", data.data +'(이)가 '+data.msg);
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('오류가 발생했습니다.');
|
||||
console.log('xhr : ', xhr);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let currentCodeGroupId; // 전역 변수로 코드 그룹 ID를 저장
|
||||
|
||||
// 코드 상세보기 모달을 표시하는 함수
|
||||
window.showDetails = function(codeGroupId) {
|
||||
currentCodeGroupId = codeGroupId; // 현재 코드 그룹 ID 저장
|
||||
$.ajax({
|
||||
url: '/api/code-details/' + codeGroupId, // API 엔드포인트
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
let detailTableBody = $('#detailTableBody');
|
||||
detailTableBody.empty();
|
||||
data.forEach(function(detail) {
|
||||
detailTableBody.append('<tr>' +
|
||||
'<td>' + detail.codeId + '</td>' +
|
||||
'<td>' + detail.codeName + '</td>' +
|
||||
'<td>' + detail.codeValue + '</td>' +
|
||||
'<td>' + detail.sortOrder + '</td>' +
|
||||
'<td>' + detail.useYn + '</td>' +
|
||||
'<td><button class="btn btn-primary btn-sm" onclick="editCodeDetail(\'' + detail.codeId + '\')">수정</button></td>' +
|
||||
'<td><button class="btn btn-danger btn-sm" onclick="deleteCodeDetail(\'' + detail.codeId + '\')">삭제</button></td>' +
|
||||
'</tr>');
|
||||
});
|
||||
$('#commonCodeDetailModal').modal('show');
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('상세 데이터를 불러오는 데 실패했습니다.');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 코드 그룹 삭제 함수
|
||||
window.deleteCodeGroup = function(codeGroupId) {
|
||||
if(confirm('삭제하시겠습니까?')) {
|
||||
$.ajax({
|
||||
url: '/api/codes/' + codeGroupId, // API 엔드포인트
|
||||
type: 'DELETE',
|
||||
success: function(response) {
|
||||
loadCodes(); // 테이블 갱신
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('오류가 발생했습니다.');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 코드 상세 추가 모달을 표시하는 함수
|
||||
window.showAddCodeDetailModal = function() {
|
||||
$('#detailCodeGroupId').val(currentCodeGroupId); // 코드 그룹 ID 필드에 현재 ID 설정
|
||||
$('#addCodeDetailModal').modal('show'); // 상세 추가 모달 표시
|
||||
};
|
||||
|
||||
// 코드 상세 추가 함수
|
||||
window.addCommonCodeDetail = function() {
|
||||
var formDataArray = $("#addCodeDetailForm").serializeArray();
|
||||
var formData = {};
|
||||
|
||||
// 배열 데이터를 JSON 객체로 변환
|
||||
$.each(formDataArray, function(_, field) {
|
||||
formData[field.name] = field.value;
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: '/api/code-details', // API 엔드포인트
|
||||
type: 'POST',
|
||||
data: JSON.stringify(formData),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
$('#addCodeDetailModal').modal('hide'); // 모달 닫기
|
||||
showDetails(formData.codeGroupId); // 상세 보기 갱신
|
||||
fn_successAlert("성공", data.data +'가 '+data.msg);
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('공통 코드 상세 추가 중 오류가 발생했습니다.');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 코드 상세 추가 함수
|
||||
window.addCodeDetail = function() {
|
||||
// 코드 상세 추가 모달을 띄우거나, 필요한 로직 추가
|
||||
};
|
||||
|
||||
// 코드 상세 수정 함수
|
||||
window.editCodeDetail = function(codeId) {
|
||||
// 코드 상세 수정 로직 추가
|
||||
};
|
||||
|
||||
// 코드 상세 삭제 함수
|
||||
window.deleteCodeDetail = function(codeId) {
|
||||
if(confirm('삭제하시겠습니까?')) {
|
||||
$.ajax({
|
||||
url: '/api/code-details/detail/' + codeId, // 변경된 URL
|
||||
type: 'DELETE',
|
||||
success: function(response) {
|
||||
showDetails($('#detailTableBody').data('group-id')); // 갱신을 위해 다시 로드
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert('오류가 발생했습니다.');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -115,17 +115,11 @@
|
||||
<!-- ./wrapper -->
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" th:href="@{/plugins/toastr/toastr.min.css}">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.6.3/papaparse.min.js"></script>
|
||||
<script th:src="@{/plugins/toastr/toastr.min.js}"></script>
|
||||
|
||||
|
||||
<script th:src="@{/plugins/toastr/toastr.min.js}"></script>
|
||||
<script>
|
||||
|
||||
|
||||
@ -89,7 +89,7 @@
|
||||
</form>
|
||||
|
||||
<p class="mb-0">
|
||||
<a th:href="@{/user/register}" class="text-center">Register a new membership</a>
|
||||
<a th:href="@{/templates/itn/user/register}" class="text-center">Register a new membership</a>
|
||||
</p>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
비밀번호가 일치하지 않습니다. 다시 입력해주세요.
|
||||
</div>
|
||||
|
||||
<form th:action="@{/user/register}" method="post" th:object="${user}" novalidate>
|
||||
<form th:action="@{/templates/itn/user/register}" method="post" th:object="${user}" novalidate>
|
||||
<!-- 검증 오류 메시지 표시 -->
|
||||
<div th:if="${#fields.hasErrors('userId')}" class="alert alert-danger" role="alert">
|
||||
<span th:errors="*{userId}"></span>
|
||||
@ -97,7 +97,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<a th:href="@{/user/login}" class="text-center">I already have a membership</a>
|
||||
<a th:href="@{/templates/itn/user/login}" class="text-center">I already have a membership</a>
|
||||
</div>
|
||||
<!-- /.form-box -->
|
||||
</div><!-- /.card -->
|
||||
|
||||
Loading…
Reference in New Issue
Block a user