Merge branch 'main' of https://git.vas2.com/geoinfo_eGov_work
commit
aeb52eccda
|
|
@ -0,0 +1 @@
|
|||
- to "C:\Users\dbnt\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\geoinfo_eGov_work\WEB-INF\views\drilling\statistics\drilling_statistics.jsp"
|
||||
7
pom.xml
7
pom.xml
|
|
@ -456,13 +456,6 @@
|
|||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc8</artifactId>
|
||||
<version>23.2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
|
|
|
|||
|
|
@ -1720,7 +1720,8 @@ public class WebConfirm
|
|||
com_code = isnull(resultSet.getString("COM_CODE"));
|
||||
}
|
||||
else {
|
||||
sql = "SELECT MAX(TO_NUMBER(COM_CODE))+1 AS MAX_CODE FROM " + tbl_name;
|
||||
sql = "SELECT MAX(TO_NUMBER(COM_CODE))+1 AS MAX_CODE FROM " + tbl_name + " " +
|
||||
"WHERE REGEXP_LIKE(COM_CODE, '^[0-9]+$')";
|
||||
query = new DatabaseQuery(sql);
|
||||
resultSet = query.execute(connection);
|
||||
if (resultSet.next()) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ public interface DrillingInputMapper {
|
|||
|
||||
public int updateProjectCodeAndProjectStateCodeByCid(HashMap<String, Object> params) throws SQLException;
|
||||
public int updateProjectCodeAndProjectStateCodeByProjectCode(HashMap<String, Object> params) throws SQLException;
|
||||
|
||||
/**
|
||||
* 건설현장 정보 상태 변경 이력을 등록합니다.
|
||||
* @param params
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public int insertConstructSiteHist(HashMap<String, Object> params) throws SQLException;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -137,14 +137,6 @@ public class DrillingInputServiceImpl implements DrillingInputService {
|
|||
params.put("userId", userId);
|
||||
|
||||
try {
|
||||
/*
|
||||
List<EgovMap> sPGetTblCsiByCidParams = drillingInputMapper.sPGetTblCsiByCid( params );
|
||||
|
||||
if( sPGetTblCsiByCidParams.size() == 0 ) {
|
||||
return params;
|
||||
}
|
||||
EgovMap tbl = sPGetTblCsiByCidParams.get(0);
|
||||
*/
|
||||
|
||||
EgovMap tbl = drillingInputMapper.getItemByCid( params );
|
||||
if( tbl != null ) {
|
||||
|
|
@ -162,6 +154,21 @@ public class DrillingInputServiceImpl implements DrillingInputService {
|
|||
}
|
||||
}
|
||||
|
||||
if (nResult > 0) { // 업데이트가 성공했을 경우에만 이력 기록
|
||||
HashMap<String, Object> histParams = new HashMap<String, Object>();
|
||||
|
||||
// 이전 상태값 (EgovMap은 보통 camelCase로 키를 반환합니다)
|
||||
Object preStateCode = tbl.get("projectStateCode");
|
||||
|
||||
histParams.put("CID", params.get("CID"));
|
||||
histParams.put("PROJECT_CODE", params.get("PROJECT_CODE"));
|
||||
histParams.put("PRE_PROJECT_STATE_CODE", preStateCode != null ? preStateCode.toString() : null); // 이전 상태
|
||||
histParams.put("PROJECT_STATE_CODE", params.get("PROJECT_STATE_CODE")); // 현재 변경된 상태
|
||||
histParams.put("MOD_REASON", "지반정보 등록 프로젝트 연결"); // 변경 사유 (필요에 따라 파라미터로 받아서 설정 가능)
|
||||
histParams.put("userId", userId);
|
||||
|
||||
drillingInputMapper.insertConstructSiteHist(histParams);
|
||||
}
|
||||
}
|
||||
return params;
|
||||
} catch (SQLException e) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import geoinfo.drilling.inquiry.service.DrillingInquiryService;
|
||||
import geoinfo.drilling.statistics.service.DrillingStatisticsService;
|
||||
import geoinfo.util.MyUtil;
|
||||
|
||||
@Controller
|
||||
|
|
@ -32,6 +33,9 @@ public class DrillingStatisticsController {
|
|||
@Autowired
|
||||
DrillingInquiryService drillingInquiryService;
|
||||
|
||||
@Autowired
|
||||
DrillingStatisticsService drillingStatisticsService;
|
||||
|
||||
@RequestMapping(value = "/drilling/statistics.do")
|
||||
public String drillingStatistics(@RequestParam HashMap<String, Object> params, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
|
|
@ -50,4 +54,37 @@ public class DrillingStatisticsController {
|
|||
|
||||
return "/drilling/statistics/drilling_notice";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/drilling/statistics/hist-list.do", method = RequestMethod.GET, produces = { "application/json; charset=utf-8" })
|
||||
@ResponseBody
|
||||
public ResponseEntity<JSONObject> drillingStatisticsHistList (
|
||||
HttpServletRequest request,
|
||||
@RequestParam HashMap<String, Object> params,
|
||||
HttpServletResponse response
|
||||
) {
|
||||
JSONObject jSONOResponse = null;
|
||||
try {
|
||||
jSONOResponse = drillingStatisticsService.getConstructSiteHistList(request, params);
|
||||
jSONOResponse.put("resultCode", 200);
|
||||
jSONOResponse.put("resultMessage", "OK");
|
||||
|
||||
} catch (Exception e) {
|
||||
jSONOResponse = new JSONObject();
|
||||
jSONOResponse.put("resultCode", -1);
|
||||
jSONOResponse.put("resultMessage", e.getMessage());
|
||||
LOGGER.error("drillingStatisticsHistList Error: ", e);
|
||||
}
|
||||
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader("Content-Type", "application/json; charset=utf-8");
|
||||
|
||||
try {
|
||||
response.getWriter().print(jSONOResponse);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Response Write Error: ", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import egovframework.rte.psl.dataaccess.util.EgovMap;
|
|||
|
||||
@Mapper("drillingStatisticsMapper")
|
||||
public interface DrillingStatisticsMapper {
|
||||
public List<EgovMap> selectConstructSiteHistList(HashMap<String, Object> params) throws SQLException;
|
||||
public Long selectConstructSiteHistListCnt(HashMap<String, Object> params) throws SQLException;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@ import egovframework.rte.psl.dataaccess.util.EgovMap;
|
|||
|
||||
|
||||
public interface DrillingStatisticsService {
|
||||
|
||||
public JSONObject getConstructSiteHistList(HttpServletRequest request, HashMap<String, Object> params) throws Exception;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import geoinfo.drilling.input.service.DrillingInputMapper;
|
|||
import geoinfo.drilling.input.service.DrillingInputService;
|
||||
import geoinfo.drilling.inquiry.service.DrillingInquiryMapper;
|
||||
import geoinfo.drilling.inquiry.service.DrillingInquiryService;
|
||||
import geoinfo.drilling.statistics.service.DrillingStatisticsMapper;
|
||||
import geoinfo.drilling.statistics.service.DrillingStatisticsService;
|
||||
import geoinfo.main.login.service.LoginMapper;
|
||||
import geoinfo.main.login.service.LoginService;
|
||||
|
|
@ -32,12 +33,16 @@ import egovframework.rte.psl.dataaccess.util.EgovMap;
|
|||
public class DrillingStatisticsServiceImpl implements DrillingStatisticsService {
|
||||
|
||||
|
||||
|
||||
@Resource(name="drillingInquiryMapper")
|
||||
private DrillingInquiryMapper drillingInquiryMapper;
|
||||
|
||||
@Resource(name="drillingInputMapper")
|
||||
private DrillingInputMapper drillingInputMapper;
|
||||
|
||||
@Resource(name="drillingStatisticsMapper")
|
||||
private DrillingStatisticsMapper drillingStatisticsMapper;
|
||||
|
||||
@Autowired
|
||||
DrillingInputService drillingInputService;
|
||||
|
||||
|
|
@ -50,4 +55,45 @@ public class DrillingStatisticsServiceImpl implements DrillingStatisticsService
|
|||
private LoginMapper loginMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public JSONObject getConstructSiteHistList(HttpServletRequest request, HashMap<String, Object> params)
|
||||
throws Exception {
|
||||
// TODO Auto-generated method stub
|
||||
JSONObject jsonResponse = new JSONObject();
|
||||
String userId = MyUtil.getStringFromObject(request.getSession().getAttribute("USERID"));
|
||||
|
||||
if (userId == null) {
|
||||
throw new Exception("로그인이 필요한 서비스입니다.");
|
||||
}
|
||||
|
||||
// 1. 현재 로그인한 사용자의 지역(영역) 코드 조회
|
||||
HashMap<String, Object> userAreaCodes = drillingInputService.getOrganizationUserGlGmGsGfCodes(userId);
|
||||
|
||||
params.put("masterCompanyOCode", MyUtil.getStringFromObject(userAreaCodes.get("v_gl")));
|
||||
params.put("masterCompanyTwCode", MyUtil.getStringFromObject(userAreaCodes.get("v_gm")));
|
||||
params.put("masterCompanyThCode", MyUtil.getStringFromObject(userAreaCodes.get("v_gs")));
|
||||
|
||||
// 2. 페이징 처리를 위한 파라미터 설정
|
||||
int page = params.get("page") == null ? 1 : Integer.parseInt(params.get("page").toString());
|
||||
int rows = params.get("rows") == null ? 10 : Integer.parseInt(params.get("rows").toString());
|
||||
params.put("firstIndex", (page - 1) * rows + 1);
|
||||
params.put("lastIndex", page * rows);
|
||||
|
||||
try {
|
||||
// 3. 총 카운트 및 목록 조회
|
||||
Long count = drillingStatisticsMapper.selectConstructSiteHistListCnt(params);
|
||||
List<EgovMap> datas = drillingStatisticsMapper.selectConstructSiteHistList(params);
|
||||
|
||||
jsonResponse.put("count", count);
|
||||
jsonResponse.put("datas", datas);
|
||||
|
||||
return jsonResponse;
|
||||
|
||||
} catch (SQLException e) {
|
||||
System.out.println("Error at getConstructSiteHistList: " + e.getMessage());
|
||||
throw new Exception("이력 조회 중 오류가 발생하였습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URLEncoder;
|
||||
|
|
@ -179,6 +180,8 @@ public class MainController
|
|||
|
||||
String src = request.getParameter("src");
|
||||
|
||||
int nCls = MyUtil.getIntegerFromObject(request.getSession().getAttribute("CLS"));
|
||||
|
||||
if( src != null && src.toLowerCase().equals("drilling") ) {
|
||||
mv.addObject("isFromDrillingSystem", true);
|
||||
} else {
|
||||
|
|
@ -206,8 +209,7 @@ public class MainController
|
|||
|
||||
} else {
|
||||
mv.addObject("isLogin", true);
|
||||
|
||||
if ("admin_user".equals(request.getSession().getAttribute("USERID").toString()) == true) {
|
||||
if ("admin_user".equals(request.getSession().getAttribute("USERID").toString()) == true || nCls == 65535) {
|
||||
EgovMap regiCount = commonService.getRegiCountAdmin();
|
||||
mv.addObject("WAIT_CNT", regiCount.get("waitCnt"));
|
||||
mv.addObject("CONFIRM_CNT", regiCount.get("confirmCnt"));
|
||||
|
|
@ -2213,7 +2215,8 @@ public class MainController
|
|||
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setContentLength(fileByte.length);
|
||||
response.setHeader("Content-Disposition", "attachment; fileName=\"" + URLEncoder.encode(filenameDn, "utf-8") + "\";");
|
||||
String headerFilename = getContentDispositionHeader( request, filenameDn);
|
||||
response.setHeader("Content-Disposition", headerFilename);
|
||||
response.setHeader("Content-Transfer-Encoding", "binary");
|
||||
response.getOutputStream().write(fileByte);
|
||||
|
||||
|
|
@ -2223,6 +2226,7 @@ public class MainController
|
|||
else
|
||||
{
|
||||
mv.addObject("msg", "<script>alert('파일을 다운받을 수 없습니다');</script>");
|
||||
response.setContentType("text/html; charset=utf-8");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.println("<script type='text/javascript'>");
|
||||
|
|
@ -2237,6 +2241,34 @@ public class MainController
|
|||
return null;
|
||||
}
|
||||
|
||||
private String getContentDispositionHeader (HttpServletRequest request, String filenameDn) throws UnsupportedEncodingException {
|
||||
// User-Agent를 통해 브라우저 정보 획득
|
||||
String userAgent = request.getHeader("User-Agent");
|
||||
|
||||
// Content-Disposition 헤더에 사용할 파일명 변수
|
||||
String headerFilename = "";
|
||||
|
||||
// IE 계열 브라우저 체크 (MSIE 또는 Trident 포함)
|
||||
if (userAgent.contains("MSIE") || userAgent.contains("Trident") || userAgent.contains("Edge")) {
|
||||
// IE, Edge 등: UTF-8로 인코딩 후, ISO-8859-1로 변환 (역호환성을 위함)
|
||||
// URLEncoder.encode 결과는 공백이 '+'로 바뀌므로, 이를 '%20'으로 치환
|
||||
headerFilename = "attachment; filename=\"" +
|
||||
new String(URLEncoder.encode(filenameDn, "UTF-8").replaceAll("\\+", " ").getBytes("UTF-8"), "ISO-8859-1") +
|
||||
"\"";
|
||||
|
||||
// **또는 더 간단한 방법 (많이 사용됨):**
|
||||
// headerFilename = "attachment; filename=\"" + URLEncoder.encode(filenameDn, "UTF-8").replaceAll("\\+", "%20") + "\"";
|
||||
|
||||
} else {
|
||||
// Chrome, Firefox 등: UTF-8 인코딩 (URL 인코딩 결과를 그대로 사용)
|
||||
headerFilename = "attachment; filename=\"" + URLEncoder.encode(filenameDn, "UTF-8").replaceAll("\\+", "%20") + "\"";
|
||||
// RFC 5987 표준을 따르는 인코딩 방식 (권장):
|
||||
// headerFilename = "attachment; filename*=UTF-8''" + URLEncoder.encode(filenameDn, "UTF-8").replaceAll("\\+", "%20");
|
||||
}
|
||||
|
||||
return headerFilename;
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/upload-file-and-up-load-su.do")
|
||||
public ModelAndView cmuboard_save(MultipartRequest multi, HttpServletRequest request, HttpServletResponse response, Map<String, Object> map) throws Exception {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import java.net.MalformedURLException;
|
|||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.jfree.util.Log;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
|
@ -575,6 +576,28 @@ public class MapContorlController {
|
|||
return "map/mapControl/deleteCart";
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/map/delete-all-cart-list.do", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public JSONObject deleteAllCartList(ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam Map<String, Object> params) throws Exception {
|
||||
|
||||
JSONObject jSONOResponse = new JSONObject();
|
||||
|
||||
String userId = request.getSession().getAttribute("USERID").toString();
|
||||
|
||||
params.put("userId", userId);
|
||||
|
||||
mapControlService.deleteAllCartList(params);
|
||||
|
||||
System.out.println("\n--------------------------------------------------------------\n" +
|
||||
request.getRequestURI() + " OUT:" +
|
||||
"\n--------------------------------------------------------------\n" +
|
||||
"jSONOResponse.toJSONString():[" + jSONOResponse.toJSONString() + "]\n" +
|
||||
"\n--------------------------------------------------------------\n");
|
||||
|
||||
return jSONOResponse;
|
||||
}
|
||||
|
||||
// 장바구니 관련 다운로드
|
||||
@RequestMapping(value = "/map/downloadCart.do", method = RequestMethod.GET)
|
||||
public String downloadPurpose(ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam Map<String, Object> params) throws Exception {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ public interface MapControlMapper {
|
|||
|
||||
void deleteCart(Map<String, Object> params) throws Exception;
|
||||
|
||||
void deleteAllCartList(Map<String, Object> params) throws Exception;
|
||||
|
||||
EgovMap selectWebCartUserId(Map<String, Object> params) throws Exception;
|
||||
|
||||
EgovMap selectWebDownloadLog(Map<String, Object> params) throws Exception;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public interface MapControlService {
|
|||
|
||||
void deleteCart(Map<String, Object> params) throws Exception;
|
||||
|
||||
void deleteAllCartList(Map<String, Object> params) throws Exception;
|
||||
|
||||
EgovMap selectWebDownloadLog(Map<String, Object> params) throws Exception;
|
||||
|
||||
EgovMap selectSichuInfoMiniDnLastPage(Map<String, Object> params) throws Exception;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,11 @@ public class MapContorlServiceImpl implements MapControlService{
|
|||
mapControlMapper.deleteCart(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAllCartList(Map<String, Object> params) throws Exception {
|
||||
mapControlMapper.deleteAllCartList(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EgovMap selectWebCartUserId(Map<String, Object> params) throws Exception {
|
||||
return mapControlMapper.selectWebCartUserId(params);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ public class CompleteController {
|
|||
// 지반정보 입력시스템 - 검수등록완료 목록
|
||||
@RequestMapping(value = "/manage/complete")
|
||||
public String complete(@RequestParam HashMap<String, Object> params, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
WebUtil wUtil = new WebUtil();
|
||||
wUtil.topTabId = "manageComplete"; // 검수일때 tab 활성화 시켜주기 위해
|
||||
// 관리자 아닐 경우 back();
|
||||
if (!request.getSession().getAttribute("CLS").equals("9")) {
|
||||
|
||||
|
|
|
|||
|
|
@ -400,88 +400,88 @@ public class HeaderController {
|
|||
@RequestMapping(value = "/web/map/mapTop.do")
|
||||
public String mapTop(@RequestParam HashMap<String, Object> params, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
//request
|
||||
String oPROJECT_CODE = StringUtils.defaultString((String) String.valueOf(params.get("PROJECT_CODE"))); //프로젝트코드
|
||||
String GUBUN = StringUtils.defaultString((String) String.valueOf(params.get("GUBUN")));
|
||||
//request
|
||||
String oPROJECT_CODE = StringUtils.defaultString((String) String.valueOf(params.get("PROJECT_CODE"))); //프로젝트코드
|
||||
String GUBUN = StringUtils.defaultString((String) String.valueOf(params.get("GUBUN")));
|
||||
|
||||
//gubun 직접입력일때
|
||||
String COORDINATE_2 = StringUtils.defaultString((String) String.valueOf(params.get("COORDINATE_2")));
|
||||
String HOLE_COORDINATE = StringUtils.defaultString((String) String.valueOf(params.get("HOLE_COORDINATE")));
|
||||
String oHOLE_CODE = StringUtils.defaultString((String) String.valueOf(params.get("HOLE_CODE")));
|
||||
String X = StringUtils.defaultString((String) String.valueOf(params.get("X")));
|
||||
String Y = StringUtils.defaultString((String) String.valueOf(params.get("Y")));
|
||||
//gubun 직접입력일때
|
||||
String COORDINATE_2 = StringUtils.defaultString((String) String.valueOf(params.get("COORDINATE_2")));
|
||||
String HOLE_COORDINATE = StringUtils.defaultString((String) String.valueOf(params.get("HOLE_COORDINATE")));
|
||||
String oHOLE_CODE = StringUtils.defaultString((String) String.valueOf(params.get("HOLE_CODE")));
|
||||
String X = StringUtils.defaultString((String) String.valueOf(params.get("X")));
|
||||
String Y = StringUtils.defaultString((String) String.valueOf(params.get("Y")));
|
||||
|
||||
WebUtil wUtil = new WebUtil();
|
||||
EgovMap map = new EgovMap();
|
||||
ArrayList array = new ArrayList();
|
||||
int count = 0;
|
||||
WebUtil wUtil = new WebUtil();
|
||||
EgovMap map = new EgovMap();
|
||||
ArrayList array = new ArrayList();
|
||||
int count = 0;
|
||||
|
||||
String fX = "";
|
||||
String fY = "";
|
||||
//좌표 가져오기
|
||||
String fX = "";
|
||||
String fY = "";
|
||||
//좌표 가져오기
|
||||
|
||||
//내용조회
|
||||
if("".equals(oPROJECT_CODE) == false){
|
||||
String sQry = "";
|
||||
//내용조회
|
||||
if("".equals(oPROJECT_CODE) == false){
|
||||
String sQry = "";
|
||||
|
||||
//시추공정보 가져오기
|
||||
if("POP".equals(GUBUN) == true){
|
||||
params.put("PROJECT_CODE", oPROJECT_CODE);
|
||||
array = headerService.getHoleInfoTrue(params);
|
||||
//시추공정보 가져오기
|
||||
if("POP".equals(GUBUN) == true){
|
||||
params.put("PROJECT_CODE", oPROJECT_CODE);
|
||||
array = headerService.getHoleInfoTrue(params);
|
||||
|
||||
|
||||
}else{
|
||||
params.put("PROJECT_CODE", oPROJECT_CODE);
|
||||
params.put("HOLE_CODE", oHOLE_CODE);
|
||||
array = headerService.getHoleInfoElse(params);
|
||||
}else{
|
||||
params.put("PROJECT_CODE", oPROJECT_CODE);
|
||||
params.put("HOLE_CODE", oHOLE_CODE);
|
||||
array = headerService.getHoleInfoElse(params);
|
||||
}
|
||||
|
||||
// Array 로 받기
|
||||
|
||||
}
|
||||
|
||||
// Array 로 받기
|
||||
if("POP".equals(GUBUN) == false && "".equals(oHOLE_CODE) == false){
|
||||
|
||||
}
|
||||
Double inX = 0.0 ;
|
||||
Double inY = 0.0 ;
|
||||
|
||||
if("POP".equals(GUBUN) == false && "".equals(oHOLE_CODE) == false){
|
||||
//degree일때
|
||||
if("Degree".equals(COORDINATE_2) == true){
|
||||
|
||||
Double inX = 0.0 ;
|
||||
Double inY = 0.0 ;
|
||||
//경위도 일때 도분초 계산
|
||||
String[] arrayX = X.split("-");
|
||||
String[] arrayY = Y.split("-");
|
||||
|
||||
//degree일때
|
||||
if("Degree".equals(COORDINATE_2) == true){
|
||||
inX = wUtil.getDegreeLatLongMS(Double.parseDouble(arrayX[0]), Double.parseDouble(arrayX[1]), Double.parseDouble(arrayX[2]));
|
||||
inY = wUtil.getDegreeLatLongMS(Double.parseDouble(arrayY[0]), Double.parseDouble(arrayY[1]), Double.parseDouble(arrayY[2]));
|
||||
fX = inX+"";
|
||||
fY = inY+"";
|
||||
|
||||
//경위도 일때 도분초 계산
|
||||
String[] arrayX = X.split("-");
|
||||
String[] arrayY = Y.split("-");
|
||||
}else{
|
||||
|
||||
inX = wUtil.getDegreeLatLongMS(Double.parseDouble(arrayX[0]), Double.parseDouble(arrayX[1]), Double.parseDouble(arrayX[2]));
|
||||
inY = wUtil.getDegreeLatLongMS(Double.parseDouble(arrayY[0]), Double.parseDouble(arrayY[1]), Double.parseDouble(arrayY[2]));
|
||||
fX = inX+"";
|
||||
fY = inY+"";
|
||||
//경위도로 변환
|
||||
HashMap map01 = wUtil.setCoordinateConvertXY(Double.parseDouble(X), Double.parseDouble(Y) , HOLE_COORDINATE , "4326");
|
||||
String tempX = wUtil.isNullOb(map01.get("X"),"0");
|
||||
String tempY = wUtil.isNullOb(map01.get("Y"),"0");
|
||||
inX = Double.parseDouble(tempX);
|
||||
inY = Double.parseDouble(tempY);
|
||||
fX = inX+"";
|
||||
fY = inY+"";
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
//경위도로 변환
|
||||
HashMap map01 = wUtil.setCoordinateConvertXY(Double.parseDouble(X), Double.parseDouble(Y) , HOLE_COORDINATE , "4326");
|
||||
String tempX = wUtil.isNullOb(map01.get("X"),"0");
|
||||
String tempY = wUtil.isNullOb(map01.get("Y"),"0");
|
||||
inX = Double.parseDouble(tempX);
|
||||
inY = Double.parseDouble(tempY);
|
||||
fX = inX+"";
|
||||
fY = inY+"";
|
||||
model.put("inX", inX);
|
||||
model.put("inY", inY);
|
||||
}
|
||||
|
||||
model.put("inX", inX);
|
||||
model.put("inY", inY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
model.put("fX", fX);
|
||||
model.put("fY", fY);
|
||||
model.put("array", array);
|
||||
model.put("gubun", GUBUN);
|
||||
model.put("oHOLE_CODE", oHOLE_CODE);
|
||||
model.put("COORDINATE_2", COORDINATE_2);
|
||||
model.put("fX", fX);
|
||||
model.put("fY", fY);
|
||||
model.put("array", array);
|
||||
model.put("gubun", GUBUN);
|
||||
model.put("oHOLE_CODE", oHOLE_CODE);
|
||||
model.put("COORDINATE_2", COORDINATE_2);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -155,4 +155,124 @@ public class HoleCoordinateController {
|
|||
return model;
|
||||
};
|
||||
|
||||
// 지반정보등록 (관리자) - 이름수정목록
|
||||
@RequestMapping(value = "/re-name.do")
|
||||
public String reName(@RequestParam HashMap<String, Object> params, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
strUtil sUtil = new strUtil();
|
||||
WebUtil wUtil = new WebUtil();
|
||||
wUtil.topTabId = "manageName"; // 검수일때 tab 활성화 시켜주기 위해
|
||||
String loginUserId = String.valueOf(request.getSession().getAttribute("USERID"));
|
||||
|
||||
// request
|
||||
String srchStartDate = sUtil.checkNull(parseData.parseData((String)params.get("startDate")));
|
||||
String srchEndDate = sUtil.checkNull(parseData.parseData((String)params.get("endDate")));
|
||||
String searchProjectName = sUtil.checkNull(parseData.parseData((String)params.get("searchProjectName")));
|
||||
String searchUserName = sUtil.checkNull(parseData.parseData((String)params.get("searchUserName")));
|
||||
String searchCreateName = sUtil.checkNull(parseData.parseData((String)params.get("searchCreateName")));
|
||||
params.put("loginUserId", loginUserId);
|
||||
|
||||
int count = 0;
|
||||
|
||||
// data조회
|
||||
// **************************************공통코드**************************************//
|
||||
String commCode = "CM016";
|
||||
String commCode02 = "'CM016'";
|
||||
|
||||
// common Array 로 받기
|
||||
ArrayList arrayCommon = commonService.getCommonCode();
|
||||
|
||||
// SelectBox형태로 map으로 받기
|
||||
HashMap<?, ?> mapCommon = wUtil.getCommCodeSel(commCode, arrayCommon, "");
|
||||
|
||||
ArrayList<?> result = masterService.getDataList(params);
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("items", result);
|
||||
count = commonService.getCommonCodeCount();
|
||||
|
||||
model.addAttribute("CM016", mapCommon.get("CM016"));
|
||||
model.addAttribute("searchProjectName", searchProjectName);
|
||||
model.addAttribute("searchUserName", searchUserName);
|
||||
model.addAttribute("searchCreateName", searchCreateName);
|
||||
model.addAttribute("loginUserId", loginUserId);
|
||||
model.addAttribute("arrayCommon", arrayCommon);
|
||||
model.addAttribute("result", result);
|
||||
model.addAttribute("json", json);
|
||||
|
||||
return "/web/manage/re_name";
|
||||
};
|
||||
|
||||
// 프로젝트명 수정 화면 (관리자)
|
||||
@RequestMapping(value = "/re-name-modify.do")
|
||||
public String reNameModify(@RequestParam HashMap<String, Object> params, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
strUtil sUtil = new strUtil();
|
||||
WebUtil wUtil = new WebUtil();
|
||||
wUtil.topTabId = "manageName"; // 검수일때 tab 활성화 시켜주기 위해
|
||||
|
||||
// request
|
||||
String PROJECT_CODE = sUtil.checkNull(parseData.parseData(String.valueOf(params.get("PROJECT_CODE"))));
|
||||
|
||||
ArrayList arrayData = new ArrayList();
|
||||
ArrayList arrayColumn = new ArrayList();
|
||||
ArrayList arrayCommon = new ArrayList();
|
||||
HashMap mapCommon = new HashMap();
|
||||
|
||||
int count = 0;
|
||||
|
||||
String PROJECT_NAME = "";
|
||||
|
||||
// data조회
|
||||
params.put("PROJECT_CODE", PROJECT_CODE);
|
||||
String pName = masterService.getCoordName(params);
|
||||
ArrayList<?> result = masterService.getCoordList(params);
|
||||
|
||||
model.addAttribute("projectCode", PROJECT_CODE);
|
||||
model.addAttribute("pName", pName);
|
||||
model.addAttribute("result", result);
|
||||
return "/web/manage/re_name_modify";
|
||||
};
|
||||
|
||||
// 좌표수정 (관리자)
|
||||
@RequestMapping(value = "/re-name-update.do")
|
||||
public ModelAndView reNameUpdate(@RequestParam HashMap<String, Object> params, ModelAndView model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
// 변수선언
|
||||
WebUtil wUtil = new WebUtil();
|
||||
strUtil sUtil = new strUtil();
|
||||
|
||||
// request
|
||||
String REPORT_TYPE = sUtil.checkNull(String.valueOf(params.get("REPORT_TYPE")));
|
||||
String PROJECT_CODE = sUtil.checkNull(String.valueOf(params.get("PROJECT_CODE")));
|
||||
String PROC = sUtil.checkNull(String.valueOf(params.get("PROC")));
|
||||
int rowCnt = 0;
|
||||
if ("".equals(sUtil.checkNull(String.valueOf(params.get("rowCnt")))) == false) {
|
||||
rowCnt = Integer.parseInt(sUtil.checkNull(String.valueOf(params.get("rowCnt"))));
|
||||
}
|
||||
// 좌표 수정 : MODIFY -- TEMP_HEADER, TBL_HEADER 수정.
|
||||
//웹 취약점 때문에 수정
|
||||
if (rowCnt > 0) {
|
||||
for (int i = 1; i < rowCnt + 1; i++) {
|
||||
String HOLE_CODE = sUtil.checkNull(String.valueOf(params.get("HOLE_CODE_" + i)));
|
||||
String HOLE_OR_X = sUtil.checkNull(String.valueOf(params.get("HOLE_OR_X_" + i)));
|
||||
String HOLE_OR_Y = sUtil.checkNull(String.valueOf(params.get("HOLE_OR_Y_" + i)));
|
||||
String HOLE_LOCATION_X = sUtil.checkNull(String.valueOf(params.get("HOLE_LOCATION_X_" + i)));
|
||||
String HOLE_LOCATION_Y = sUtil.checkNull(String.valueOf(params.get("HOLE_LOCATION_Y_" + i)));
|
||||
// 경위도 -> GRS80 중부원점 20-60 좌표로 변환
|
||||
Map map = wUtil.setCoordinateChgXY(Double.parseDouble(HOLE_LOCATION_X), Double.parseDouble(HOLE_LOCATION_Y), "4326", "5186");
|
||||
|
||||
params.put("HOLE_CODE", HOLE_CODE);
|
||||
params.put("HOLE_OR_X", HOLE_OR_X);
|
||||
params.put("HOLE_OR_Y", HOLE_OR_Y);
|
||||
params.put("HOLE_LOCATION_X", HOLE_LOCATION_X);
|
||||
params.put("HOLE_LOCATION_Y", HOLE_LOCATION_Y);
|
||||
params.put("tmX", map.get("X").toString());
|
||||
params.put("tmY", map.get("Y").toString());
|
||||
masterService.upCoord1(params);
|
||||
masterService.upCoord2(params);
|
||||
}
|
||||
}
|
||||
|
||||
model.setViewName("redirect:/re-name.do");
|
||||
|
||||
return model;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public class ManageListController {
|
|||
return "/web/manage/list";
|
||||
};
|
||||
|
||||
// 지반정보등록 (관리자)
|
||||
// 지반정보등록 (관리자) - 일반 입력자도 여기 로직을 통해 화면이 보여짐.
|
||||
@RequestMapping(value = "/meta_info.do")
|
||||
public String meta_info(@RequestParam HashMap<String, Object> params,
|
||||
ModelMap model, HttpServletRequest request,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
public class MyPermission {
|
||||
|
||||
// 1. 각 권한에 대한 플래그를 2의 거듭제곱으로 정의합니다.
|
||||
public static final int PERMISSION_NONE = 0; // 0000
|
||||
public static final int PERMISSION_READ = 1; // 0001
|
||||
public static final int PERMISSION_WRITE = 2; // 0010
|
||||
public static final int PERMISSION_EXECUTE = 4; // 0100
|
||||
public static final int PERMISSION_DELETE = 8; // 1000
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// 2. 여러 권한을 하나의 정수 변수에 할당 (읽기 + 쓰기 권한 부여)
|
||||
int myPermissions = PERMISSION_READ | PERMISSION_WRITE; // 1 | 2 = 3 (0011)
|
||||
|
||||
System.out.println("초기 권한 설정 (읽기, 쓰기)");
|
||||
printPermissions(myPermissions);
|
||||
|
||||
// 3. 특정 권한이 있는지 확인
|
||||
System.out.println("\n--- 권한 확인 ---");
|
||||
// (myPermissions & PERMISSION_READ) != 0 으로 체크해도 동일합니다.
|
||||
if ((myPermissions & PERMISSION_READ) == PERMISSION_READ) {
|
||||
System.out.println("결과: 읽기 권한이 있습니다.");
|
||||
}
|
||||
if ((myPermissions & PERMISSION_EXECUTE) == PERMISSION_EXECUTE) {
|
||||
System.out.println("결과: 실행 권한이 있습니다.");
|
||||
} else {
|
||||
System.out.println("결과: 실행 권한이 없습니다.");
|
||||
}
|
||||
|
||||
// 4. 기존 권한에 새로운 권한 추가 (실행 권한 추가)
|
||||
System.out.println("\n--- 실행 권한 추가 ---");
|
||||
myPermissions |= PERMISSION_EXECUTE; // myPermissions = myPermissions | PERMISSION_EXECUTE;
|
||||
printPermissions(myPermissions);
|
||||
|
||||
// 5. 특정 권한 제거 (쓰기 권한 제거)
|
||||
System.out.println("\n--- 쓰기 권한 제거 ---");
|
||||
myPermissions &= ~PERMISSION_WRITE; // myPermissions = myPermissions & ~PERMISSION_WRITE;
|
||||
printPermissions(myPermissions);
|
||||
|
||||
// 6. 권한 토글 (XOR 연산, 있으면 없애고 없으면 추가)
|
||||
System.out.println("\n--- 읽기 권한 토글 (제거) ---");
|
||||
myPermissions ^= PERMISSION_READ;
|
||||
printPermissions(myPermissions);
|
||||
|
||||
System.out.println("\n--- 읽기 권한 토글 (다시 추가) ---");
|
||||
myPermissions ^= PERMISSION_READ;
|
||||
printPermissions(myPermissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 설정된 권한 상태를 출력하는 헬퍼 메서드
|
||||
*/
|
||||
public static void printPermissions(int permissions) {
|
||||
System.out.println("현재 권한 값 (Decimal): " + permissions);
|
||||
System.out.println("현재 권한 값 (Binary): " + Integer.toBinaryString(permissions));
|
||||
|
||||
System.out.print("포함된 권한: ");
|
||||
if ((permissions & PERMISSION_READ) == PERMISSION_READ) System.out.print("READ ");
|
||||
if ((permissions & PERMISSION_WRITE) == PERMISSION_WRITE) System.out.print("WRITE ");
|
||||
if ((permissions & PERMISSION_EXECUTE) == PERMISSION_EXECUTE) System.out.print("EXECUTE ");
|
||||
if ((permissions & PERMISSION_DELETE) == PERMISSION_DELETE) System.out.print("DELETE ");
|
||||
if (permissions == PERMISSION_NONE) System.out.print("NONE");
|
||||
System.out.println("\n---------------------------------");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
package geoinfo.videos;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import egovframework.com.cmm.service.EgovProperties;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/video")
|
||||
public class VideoStreamingController {
|
||||
|
||||
// 동영상 파일이 저장된 기본 경로
|
||||
private final String VIDEO_DIRECTORY = EgovProperties.getProperty("Geoinfo.FilePath") + "videos";
|
||||
|
||||
@RequestMapping(value = "/stream.do", method = RequestMethod.GET)
|
||||
public void streamVideo(@RequestParam("name") String videoName, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
// 1. 경로 및 파일 유효성 검사
|
||||
if (!StringUtils.hasText(videoName)) {
|
||||
sendError(response, "비디오 파일명이 비어있습니다.", HttpServletResponse.SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
// URL 인코딩된 파일 이름 디코딩
|
||||
String decodedVideoName;
|
||||
try {
|
||||
decodedVideoName = URLDecoder.decode(videoName, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
sendError(response, "비디오 파일명 디코딩에 실패했습니다.", HttpServletResponse.SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
File videoFile = new File(VIDEO_DIRECTORY, decodedVideoName);
|
||||
|
||||
// Path Traversal 공격을 방지하기 위한 보안 코드 추가
|
||||
try {
|
||||
String videoDirPath = new File(VIDEO_DIRECTORY).getCanonicalPath();
|
||||
String requestedFilePath = videoFile.getCanonicalPath();
|
||||
|
||||
// 요청된 파일의 실제 경로가 허용된 비디오 디렉토리 내에 있는지 확인
|
||||
if (!requestedFilePath.startsWith(videoDirPath)) {
|
||||
sendError(response, "잘못된 파일 경로입니다.", HttpServletResponse.SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// 경로 처리 중 오류 발생
|
||||
sendError(response, "파일 경로 처리 중 오류가 발생했습니다.", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!videoFile.exists() || !videoFile.isFile()) {
|
||||
sendError(response, "요청하신 동영상 파일을 찾을 수 없습니다.", HttpServletResponse.SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
RandomAccessFile randomFile = null;
|
||||
OutputStream outputStream = null;
|
||||
|
||||
try {
|
||||
long rangeStart = 0;
|
||||
long rangeEnd = 0;
|
||||
boolean isRangeRequest = false;
|
||||
|
||||
// 2. Range 헤더 파싱
|
||||
String rangeHeader = request.getHeader("Range");
|
||||
if (rangeHeader != null && rangeHeader.startsWith("bytes=")) {
|
||||
isRangeRequest = true;
|
||||
rangeHeader = rangeHeader.substring("bytes=".length());
|
||||
String[] ranges = rangeHeader.split("-");
|
||||
try {
|
||||
rangeStart = Long.parseLong(ranges[0]);
|
||||
if (ranges.length > 1) {
|
||||
rangeEnd = Long.parseLong(ranges[1]);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Range 형식이 잘못된 경우 무시하고 전체 전송 시도
|
||||
rangeStart = 0;
|
||||
rangeEnd = 0;
|
||||
isRangeRequest = false;
|
||||
}
|
||||
}
|
||||
|
||||
long fileLength = videoFile.length();
|
||||
|
||||
// Range 헤더가 없거나 잘못된 경우, rangeEnd를 파일 끝으로 설정
|
||||
if (rangeEnd == 0) {
|
||||
rangeEnd = fileLength - 1;
|
||||
}
|
||||
|
||||
// 3. 응답 헤더 설정
|
||||
String fileName = videoFile.getName();
|
||||
String mimeType = "video/mp4"; // video/webm, video/ogg 등 파일에 맞게 설정
|
||||
|
||||
// 브라우저별 한글 파일명 처리
|
||||
String header = request.getHeader("User-Agent");
|
||||
String encodedFilename;
|
||||
if (header.contains("MSIE") || header.contains("Trident")) { // IE, Edge
|
||||
encodedFilename = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
|
||||
} else { // Chrome, Firefox, Opera
|
||||
encodedFilename = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
|
||||
}
|
||||
|
||||
response.setHeader("Content-Disposition", "inline; filename=\"" + encodedFilename + "\"");
|
||||
response.setContentType(mimeType);
|
||||
response.setHeader("Accept-Ranges", "bytes");
|
||||
|
||||
long rangeLength = rangeEnd - rangeStart + 1;
|
||||
|
||||
if (isRangeRequest) {
|
||||
// 스트리밍 (부분 전송)
|
||||
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206
|
||||
response.setHeader("Content-Length", String.valueOf(rangeLength));
|
||||
response.setHeader("Content-Range", "bytes " + rangeStart + "-" + rangeEnd + "/" + fileLength);
|
||||
} else {
|
||||
// 전체 전송
|
||||
response.setStatus(HttpServletResponse.SC_OK); // 200
|
||||
response.setHeader("Content-Length", String.valueOf(fileLength));
|
||||
}
|
||||
|
||||
// 4. 파일 데이터 전송
|
||||
randomFile = new RandomAccessFile(videoFile, "r");
|
||||
randomFile.seek(rangeStart);
|
||||
|
||||
outputStream = response.getOutputStream();
|
||||
byte[] buffer = new byte[8192]; // 8KB 버퍼
|
||||
int bytesRead;
|
||||
|
||||
long bytesToWrite = rangeLength;
|
||||
while (bytesToWrite > 0 && (bytesRead = randomFile.read(buffer, 0, (int) Math.min(bytesToWrite, buffer.length))) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
bytesToWrite -= bytesRead;
|
||||
}
|
||||
|
||||
outputStream.flush();
|
||||
|
||||
} catch (IOException e) {
|
||||
// 클라이언트가 연결을 중단하는 경우 (예: 동영상 탐색) IOException이 발생할 수 있음
|
||||
// 이 경우는 정상적인 동작이므로 에러 로그를 남기지 않음
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
sendError(response, "알 수 없는 오류가 발생했습니다.", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
} finally {
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
if (randomFile != null) {
|
||||
try {
|
||||
randomFile.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 클라이언트에게 에러 메시지를 전송하는 메소드.
|
||||
* 한글 깨짐을 방지하기 위해 응답 인코딩을 UTF-8로 직접 설정합니다.
|
||||
* @param response HttpServletResponse 객체
|
||||
* @param message 전송할 에러 메시지
|
||||
* @param status HTTP 상태 코드
|
||||
*/
|
||||
private void sendError(HttpServletResponse response, String message, int status) {
|
||||
try {
|
||||
// 1. 응답 상태 코드를 직접 설정합니다.
|
||||
response.setStatus(status);
|
||||
|
||||
// 2. 응답의 컨텐츠 타입과 문자 인코딩을 UTF-8로 명확하게 지정합니다.
|
||||
response.setContentType("text/plain; charset=UTF-8");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
|
||||
// 3. 응답 본문에 직접 에러 메시지를 작성합니다.
|
||||
response.getWriter().write(message);
|
||||
response.getWriter().flush();
|
||||
|
||||
} catch (IOException e) {
|
||||
// 클라이언트가 연결을 끊었거나 다른 I/O 오류 발생 시
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -132,4 +132,26 @@
|
|||
]]>
|
||||
</update>
|
||||
|
||||
<insert id="insertConstructSiteHist" parameterType="map">
|
||||
INSERT INTO TEMP_CONSTRUCT_SITE_HIST (
|
||||
HIST_ID,
|
||||
CID,
|
||||
PROJECT_CODE,
|
||||
PRE_PROJECT_STATE_CODE,
|
||||
PROJECT_STATE_CODE,
|
||||
MOD_REASON,
|
||||
MOD_USERID,
|
||||
MOD_DT
|
||||
) VALUES (
|
||||
CONSTRUCT_SITE_HIST_SEQ.NEXTVAL,
|
||||
#{CID},
|
||||
#{PROJECT_CODE},
|
||||
#{PRE_PROJECT_STATE_CODE},
|
||||
#{PROJECT_STATE_CODE},
|
||||
#{MOD_REASON},
|
||||
#{userId},
|
||||
SYSTIMESTAMP
|
||||
)
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -3,4 +3,58 @@
|
|||
|
||||
<mapper namespace="geoinfo.drilling.statistics.service.DrillingStatisticsMapper">
|
||||
|
||||
<select id="selectConstructSiteHistList" parameterType="map" resultType="egovMap">
|
||||
SELECT
|
||||
*
|
||||
FROM (
|
||||
SELECT
|
||||
ROW_NUMBER() OVER(ORDER BY h.MOD_DT DESC) AS RNUM,
|
||||
h.HIST_ID,
|
||||
h.CID,
|
||||
csi.CONST_NAME,
|
||||
h.PROJECT_CODE,
|
||||
h.PRE_PROJECT_STATE_CODE,
|
||||
h.PROJECT_STATE_CODE,
|
||||
h.MOD_REASON,
|
||||
h.MOD_USERID,
|
||||
TO_CHAR(h.MOD_DT, 'YYYY-MM-DD HH24:MI:SS') AS MOD_DT
|
||||
FROM
|
||||
TEMP_CONSTRUCT_SITE_HIST h
|
||||
JOIN
|
||||
TEMP_CONSTRUCT_SITE_INFO csi ON h.CID = csi.CID
|
||||
WHERE
|
||||
1=1
|
||||
<if test="masterCompanyOCode != null and masterCompanyOCode != ''">
|
||||
AND csi.MASTER_COMPANY_O_CODE = #{masterCompanyOCode}
|
||||
</if>
|
||||
<if test="masterCompanyTwCode != null and masterCompanyTwCode != ''">
|
||||
AND csi.MASTER_COMPANY_TW_CODE = #{masterCompanyTwCode}
|
||||
</if>
|
||||
<if test="masterCompanyThCode != null and masterCompanyThCode != ''">
|
||||
AND csi.MASTER_COMPANY_TH_CODE = #{masterCompanyThCode}
|
||||
</if>
|
||||
)
|
||||
WHERE RNUM BETWEEN #{firstIndex} AND #{lastIndex}
|
||||
</select>
|
||||
|
||||
<select id="selectConstructSiteHistListCnt" parameterType="map" resultType="long">
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
TEMP_CONSTRUCT_SITE_HIST h
|
||||
JOIN
|
||||
TEMP_CONSTRUCT_SITE_INFO csi ON h.CID = csi.CID
|
||||
WHERE
|
||||
1=1
|
||||
<if test="masterCompanyOCode != null and masterCompanyOCode != ''">
|
||||
AND csi.MASTER_COMPANY_O_CODE = #{masterCompanyOCode}
|
||||
</if>
|
||||
<if test="masterCompanyTwCode != null and masterCompanyTwCode != ''">
|
||||
AND csi.MASTER_COMPANY_TW_CODE = #{masterCompanyTwCode}
|
||||
</if>
|
||||
<if test="masterCompanyThCode != null and masterCompanyThCode != ''">
|
||||
AND csi.MASTER_COMPANY_TH_CODE = #{masterCompanyThCode}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -444,6 +444,16 @@
|
|||
|
||||
</update>
|
||||
|
||||
<delete id="deleteAllCartList">
|
||||
<![CDATA[
|
||||
DELETE
|
||||
FROM
|
||||
WEB_CART wc
|
||||
WHERE
|
||||
TRIM(wc.USERID) = #{userId}
|
||||
]]>
|
||||
</delete>
|
||||
|
||||
<select id="selectWebCartUserId" parameterType="map" resultType="egovMap">
|
||||
<![CDATA[
|
||||
SELECT
|
||||
|
|
|
|||
|
|
@ -247,8 +247,15 @@ function goPage(page) {
|
|||
<td>
|
||||
<table width="100%" border=0>
|
||||
<tr>
|
||||
<td height="19" valign="top"><img src="/body/map/download/image/btn_allselect.gif" onClick="javascript:allSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand"><img src="/images/menu04/spacer.gif" width="10" height="19"><img src="/body/map/download/image/btn_deselect.gif" onClick="javascript:allDeSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand">
|
||||
<img src="/images/menu04/spacer.gif" width="10" height="19"><img src="/body/map/download/image/btn_download.gif" onClick="javascript:downloadNew('<c:out value='${params.cnt}'/>')" style="cursor: hand"></td>
|
||||
<td height="19" valign="top">
|
||||
<img src="/body/map/download/image/btn_delete_all.gif" onClick="javascript:deleteAllCartList()" style="cursor: pointer">
|
||||
<img src="/images/menu04/spacer.gif" width="10" height="19">
|
||||
<img src="/body/map/download/image/btn_allselect.gif" onClick="javascript:allSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand">
|
||||
<img src="/images/menu04/spacer.gif" width="10" height="19">
|
||||
<img src="/body/map/download/image/btn_deselect.gif" onClick="javascript:allDeSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand">
|
||||
<img src="/images/menu04/spacer.gif" width="10" height="19">
|
||||
<img src="/body/map/download/image/btn_download.gif" onClick="javascript:downloadNew('<c:out value='${params.cnt}'/>')" style="cursor: hand">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
|
||||
|
||||
<%
|
||||
|
||||
|
||||
if (request.getSession().getAttribute("USERID") == null) {
|
||||
|
||||
%>
|
||||
<script>alert('로그인후 이용하실 수 있습니다.');window.location.href='/index.do';</script>
|
||||
<%
|
||||
|
|
@ -15,9 +12,7 @@ if (request.getSession().getAttribute("USERID") == null) {
|
|||
}
|
||||
%>
|
||||
<%
|
||||
|
||||
if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSession().getAttribute("CLS") ) == false ) {
|
||||
|
||||
%>
|
||||
<script>alert('발주 기관 회원만 이용가능합니다.');window.location.href='/index.do';</script>
|
||||
<%
|
||||
|
|
@ -25,23 +20,14 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
|
|||
}
|
||||
%>
|
||||
|
||||
|
||||
|
||||
<%@ include file="/include/inc_head_2021_new.jsp" %>
|
||||
|
||||
|
||||
<!-- header start-->
|
||||
<c:import url="/drilling/common/includeTopMenu.do" charEncoding="UTF-8" />
|
||||
<!-- Tailwind CSS CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<!-- Chart.js CDN for creating charts -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<!-- Google Fonts: Inter -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Noto+Sans+KR:wght@400;500;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- header end-->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Noto+Sans+KR:wght@400;500;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
@keyframes shake {
|
||||
|
|
@ -57,98 +43,74 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
|
|||
90% { transform: translateX(-5px); }
|
||||
100% { transform: translateX(0); }
|
||||
}
|
||||
|
||||
.shake-animation {
|
||||
animation: shake 0.6s;
|
||||
}
|
||||
|
||||
/* The snackbar - position it at the bottom and in the middle of the screen */
|
||||
#snackbar {
|
||||
visibility: hidden; /* Hidden by default. Visible on click */
|
||||
min-width: 250px; /* Set a default minimum width */
|
||||
margin-left: -125px; /* Divide value of min-width by 2 */
|
||||
background-color: #000000; /* Black background color */
|
||||
color: #ff0000; /* White text color */
|
||||
text-align: center; /* Centered text */
|
||||
border-radius: 2px; /* Rounded borders */
|
||||
padding: 16px; /* Padding */
|
||||
position: fixed; /* Sit on top of the screen */
|
||||
z-index: 1; /* Add a z-index if needed */
|
||||
left: 50%; /* Center the snackbar */
|
||||
bottom: 80px; /* 30px from the bottom */
|
||||
visibility: hidden;
|
||||
min-width: 250px;
|
||||
margin-left: -125px;
|
||||
background-color: #000000;
|
||||
color: #ff0000;
|
||||
text-align: center;
|
||||
border-radius: 2px;
|
||||
padding: 16px;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: 50%;
|
||||
bottom: 80px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Show the snackbar when clicking on a button (class added with JavaScript) */
|
||||
#snackbar.show {
|
||||
visibility: visible; /* Show the snackbar */
|
||||
/* Add animation: Take 0.5 seconds to fade in and out the snackbar.
|
||||
However, delay the fade out process for 2.5 seconds */
|
||||
visibility: visible;
|
||||
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
|
||||
animation: fadein 0.5s, fadeout 0.5s 2.5s;
|
||||
}
|
||||
|
||||
/* Animations to fade the snackbar in and out */
|
||||
@-webkit-keyframes fadein {
|
||||
from {bottom: 0; opacity: 0;}
|
||||
to {bottom: 80px; opacity: 1;}
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {bottom: 0; opacity: 0;}
|
||||
to {bottom: 80px; opacity: 1;}
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeout {
|
||||
from {bottom: 80px; opacity: 1;}
|
||||
to {bottom: 0; opacity: 0;}
|
||||
}
|
||||
|
||||
@keyframes fadeout {
|
||||
from {bottom: 80px; opacity: 1;}
|
||||
to {bottom: 0; opacity: 0;}
|
||||
}
|
||||
|
||||
|
||||
#suggestionList {
|
||||
border: 1px solid #ccc;
|
||||
width: 300px; /* 입력창 너비에 맞춰 조절 */
|
||||
position_: absolute;
|
||||
background-color: white;
|
||||
display: none;
|
||||
left: 91px;
|
||||
top: 54px;
|
||||
z-index: 3;
|
||||
}
|
||||
#suggestionList div {
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#suggestionList div:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
#suggestionList div .organizational-structure {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#const-state-code {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
|
||||
#suggestionList {
|
||||
border: 1px solid #ccc;
|
||||
width: 300px;
|
||||
position_: absolute;
|
||||
background-color: white;
|
||||
display: none;
|
||||
left: 91px;
|
||||
top: 54px;
|
||||
z-index: 3;
|
||||
}
|
||||
#suggestionList div {
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#suggestionList div:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
#suggestionList div .organizational-structure {
|
||||
color: red;
|
||||
}
|
||||
#const-state-code {
|
||||
width: 160px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- javascript start-->
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
</script>
|
||||
<!-- javascript end-->
|
||||
|
||||
<!-- 페이지 컨테이너 시작 -->
|
||||
<section class="drilling-page-container">
|
||||
<div class="page-content-wrapper drilling inquiry">
|
||||
<!-- 서브메뉴 시작 -->
|
||||
<div class="page-sidebar-wrapper">
|
||||
<div class="page-sidebar">
|
||||
<div class="treeview-project-name">
|
||||
|
|
@ -158,12 +120,8 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 서브메뉴 끝 -->
|
||||
|
||||
<!-- 콘텐츠 시작 -->
|
||||
<div class="page-content">
|
||||
<div class="page-content-inner">
|
||||
<!-- 카테고리 시작 -->
|
||||
<div class="category-wrapper">
|
||||
<ul class="page-category">
|
||||
<li class="category-item"></li>
|
||||
|
|
@ -171,231 +129,261 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
|
|||
</ul>
|
||||
<a href="#" class="btn btn-help">도움말</a>
|
||||
</div>
|
||||
<!-- 카테고리 끝 -->
|
||||
<h1 class="page-title-1depth">통계</h1>
|
||||
<!-- 내용 시작 -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Main Content -->
|
||||
<main class="flex flex-col lg:flex-row gap-4">
|
||||
<!-- Right Sidebar -->
|
||||
<aside class="w-full flex flex-col gap-4">
|
||||
<!-- Wrapper div for side-by-side layout on large screens -->
|
||||
<div class="flex flex-col lg:flex-row gap-4">
|
||||
<!-- Project Status Chart -->
|
||||
<div class="w-full lg:w-1/2 bg-white p-4 rounded-lg shadow-md">
|
||||
<h3 class="font-semibold text-gray-800 mb-2 text-4xl">건설현장 프로젝트 입력상태 별 그래프</h3>
|
||||
<div class="w-full h-[28rem] flex justify-center items-center">
|
||||
<canvas id="projectStatusChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<main class="flex flex-col lg:flex-row gap-4">
|
||||
<aside class="w-full flex flex-col gap-4">
|
||||
<div class="flex flex-col lg:flex-row gap-4">
|
||||
<div class="w-full lg:w-1/2 bg-white p-4 rounded-lg shadow-md">
|
||||
<h3 class="font-semibold text-gray-800 mb-2 text-4xl">건설현장 프로젝트 입력상태 별 그래프</h3>
|
||||
<div class="w-full h-[28rem] flex justify-center items-center">
|
||||
<canvas id="projectStatusChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notifications -->
|
||||
<div class="w-full lg:w-1/2 bg-white p-4 rounded-lg shadow-md flex flex-col">
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h3 class="font-semibold text-gray-800 text-4xl">알림 내역</h3>
|
||||
<a href="../drilling/notice.do" class="text-3xl text-blue-600 hover:underline">모두 보기</a>
|
||||
</div>
|
||||
<div class="space-y-3 flex-grow">
|
||||
<div class="flex items-start p-2 bg-blue-50 rounded-lg">
|
||||
<div class="bg-blue-500 text-white rounded-full h-8 w-8 flex-shrink-0 flex items-center justify-center mr-3">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-3xl font-medium text-gray-800">수정 요청</p>
|
||||
<p class="text-2xl text-gray-600">'제3연륙교 건설 공사' 프로젝트의 시추정보 수정이 필요합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start p-2 rounded-lg">
|
||||
<div class="bg-green-500 text-white rounded-full h-8 w-8 flex-shrink-0 flex items-center justify-center mr-3">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-3xl font-medium text-gray-800">검수 완료</p>
|
||||
<p class="text-2xl text-gray-600">'충북선 달천 충주간' 프로젝트가 검수 완료되었습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full lg:w-1/2 bg-white p-4 rounded-lg shadow-md flex flex-col">
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h3 class="font-semibold text-gray-800 text-4xl">알림 내역</h3>
|
||||
<a href="/drilling/notice.do" class="text-3xl text-blue-600 hover:underline">모두 보기</a>
|
||||
</div>
|
||||
|
||||
<!-- Report Download Section -->
|
||||
<div class="bg-white p-4 rounded-lg shadow-md">
|
||||
<h3 class="font-semibold text-gray-800 mb-2 text-4xl">통계 보고서 다운로드</h3>
|
||||
<p class="text-2xl text-gray-600 mb-4">발주기관 통계 기능을 보고서 형태로 다운로드 받을 수 있습니다.</p>
|
||||
<!-- MODIFIED: Changed grid to 3 columns to allow for different chart widths -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
|
||||
<!-- MODIFIED: Set column span to 1 -->
|
||||
<div class="md:col-span-1 flex flex-col items-center">
|
||||
<h4 class="text-2xl font-medium text-center text-gray-700 mb-2">위험도 현황</h4>
|
||||
<div class="relative h-96 w-96">
|
||||
<canvas id="riskChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MODIFIED: Set column span to 2 to make it twice as wide -->
|
||||
<div class="md:col-span-2 flex flex-col items-center">
|
||||
<h4 class="text-2xl font-medium text-center text-gray-700 mb-2">프로젝트 재정 현황</h4>
|
||||
<!-- MODIFIED: Changed width to w-full to fill the new column span -->
|
||||
<div class="relative h-96 w-full">
|
||||
<canvas id="financialChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MODIFIED: Wrapped button in a flex container to center it and reduced its width -->
|
||||
<div class="flex justify-center">
|
||||
<!-- MODIFIED: Reduced width from md:w-1/4 to md:w-[15%] (40% reduction) -->
|
||||
<button class="w-full md:w-[15%] bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded-lg flex items-center justify-center transition duration-300 text-3xl">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
|
||||
PDF로 내보내기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</main>
|
||||
<%-- ▼▼▼ [수정] 기존 하드코딩된 알림 내역을 삭제하고, id를 부여합니다. ▼▼▼ --%>
|
||||
<div id="notification-list" class="space-y-3 flex-grow">
|
||||
</div>
|
||||
<%-- ▲▲▲ [수정] 여기까지 ▲▲▲ --%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Chart.js initialization
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// 1. Project Status Pie Chart
|
||||
const ctxProjectStatus = document.getElementById('projectStatusChart').getContext('2d');
|
||||
new Chart(ctxProjectStatus, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['등록완료', '미입력', '검수중', '수정요청'],
|
||||
datasets: [{
|
||||
label: '프로젝트 상태',
|
||||
data: [34, 32, 18, 16],
|
||||
backgroundColor: [
|
||||
'rgba(239, 68, 68, 0.8)', // Red
|
||||
'rgba(245, 158, 11, 0.8)', // Amber
|
||||
'rgba(16, 185, 129, 0.8)', // Emerald
|
||||
'rgba(59, 130, 246, 0.8)' // Blue
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(239, 68, 68, 1)',
|
||||
'rgba(245, 158, 11, 1)',
|
||||
'rgba(16, 185, 129, 1)',
|
||||
'rgba(59, 130, 246, 1)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
let label = context.label || '';
|
||||
if (label) {
|
||||
label += ': ';
|
||||
<div class="bg-white p-4 rounded-lg shadow-md">
|
||||
<h3 class="font-semibold text-gray-800 mb-2 text-4xl">통계 보고서 다운로드</h3>
|
||||
<p class="text-2xl text-gray-600 mb-4">발주기관 통계 기능을 보고서 형태로 다운로드 받을 수 있습니다.</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
|
||||
<div class="md:col-span-1 flex flex-col items-center">
|
||||
<h4 class="text-2xl font-medium text-center text-gray-700 mb-2">위험도 현황</h4>
|
||||
<div class="relative h-96 w-96">
|
||||
<canvas id="riskChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md:col-span-2 flex flex-col items-center">
|
||||
<h4 class="text-2xl font-medium text-center text-gray-700 mb-2">프로젝트 재정 현황</h4>
|
||||
<div class="relative h-96 w-full">
|
||||
<canvas id="financialChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<button class="w-full md:w-[15%] bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded-lg flex items-center justify-center transition duration-300 text-3xl">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
|
||||
PDF로 내보내기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
// Chart.js initialization
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 1. Project Status Pie Chart
|
||||
var ctxProjectStatus = document.getElementById('projectStatusChart').getContext('2d');
|
||||
new Chart(ctxProjectStatus, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['등록완료', '미입력', '검수중', '수정요청'],
|
||||
datasets: [{
|
||||
label: '프로젝트 상태',
|
||||
data: [34, 32, 18, 16],
|
||||
backgroundColor: [ 'rgba(239, 68, 68, 0.8)', 'rgba(245, 158, 11, 0.8)', 'rgba(16, 185, 129, 0.8)', 'rgba(59, 130, 246, 0.8)' ],
|
||||
borderColor: [ 'rgba(239, 68, 68, 1)', 'rgba(245, 158, 11, 1)', 'rgba(16, 185, 129, 1)', 'rgba(59, 130, 246, 1)' ],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: { position: 'top' },
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
var label = context.label || '';
|
||||
if (label) { label += ': '; }
|
||||
if (context.parsed !== null) { label += context.parsed + '%'; }
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (context.parsed !== null) {
|
||||
label += context.parsed + '%';
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 2. Risk Status Donut Chart
|
||||
const ctxRisk = document.getElementById('riskChart').getContext('2d');
|
||||
new Chart(ctxRisk, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ['낮은 위험', '중간 위험', '높은 위험'],
|
||||
datasets: [{
|
||||
data: [41, 22, 37],
|
||||
backgroundColor: [
|
||||
'rgba(34, 197, 94, 0.8)', // Green
|
||||
'rgba(245, 158, 11, 0.8)', // Amber
|
||||
'rgba(239, 68, 68, 0.8)' // Red
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(34, 197, 94, 1)',
|
||||
'rgba(245, 158, 11, 1)',
|
||||
'rgba(239, 68, 68, 1)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
boxWidth: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 3. Financial Status Bar Chart
|
||||
const ctxFinancial = document.getElementById('financialChart').getContext('2d');
|
||||
new Chart(ctxFinancial, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['프로젝트 A', '프로젝트 B', '프로젝트 C', '프로젝트 D'],
|
||||
datasets: [{
|
||||
label: '예산',
|
||||
data: [65, 59, 80, 81],
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.7)',
|
||||
borderColor: 'rgba(59, 130, 246, 1)',
|
||||
borderWidth: 1
|
||||
}, {
|
||||
label: '실제 비용',
|
||||
data: [45, 49, 60, 70],
|
||||
backgroundColor: 'rgba(239, 68, 68, 0.7)',
|
||||
borderColor: 'rgba(239, 68, 68, 1)',
|
||||
borderWidth: 1
|
||||
},{
|
||||
label: '예상 비용',
|
||||
data: [75, 69, 90, 91],
|
||||
backgroundColor: 'rgba(16, 185, 129, 0.7)',
|
||||
borderColor: 'rgba(16, 185, 129, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
callback: function(value) {
|
||||
return value + '억';
|
||||
// 2. Risk Status Donut Chart
|
||||
var ctxRisk = document.getElementById('riskChart').getContext('2d');
|
||||
new Chart(ctxRisk, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ['낮은 위험', '중간 위험', '높은 위험'],
|
||||
datasets: [{
|
||||
data: [41, 22, 37],
|
||||
backgroundColor: [ 'rgba(34, 197, 94, 0.8)', 'rgba(245, 158, 11, 0.8)', 'rgba(239, 68, 68, 0.8)' ],
|
||||
borderColor: [ 'rgba(34, 197, 94, 1)', 'rgba(245, 158, 11, 1)', 'rgba(239, 68, 68, 1)' ],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: { legend: { position: 'bottom', labels: { boxWidth: 12 } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
});
|
||||
// 3. Financial Status Bar Chart
|
||||
var ctxFinancial = document.getElementById('financialChart').getContext('2d');
|
||||
new Chart(ctxFinancial, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['프로젝트 A', '프로젝트 B', '프로젝트 C', '프로젝트 D'],
|
||||
datasets: [{
|
||||
label: '예산',
|
||||
data: [65, 59, 80, 81],
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.7)',
|
||||
borderColor: 'rgba(59, 130, 246, 1)',
|
||||
borderWidth: 1
|
||||
}, {
|
||||
label: '실제 비용',
|
||||
data: [45, 49, 60, 70],
|
||||
backgroundColor: 'rgba(239, 68, 68, 0.7)',
|
||||
borderColor: 'rgba(239, 68, 68, 1)',
|
||||
borderWidth: 1
|
||||
},{
|
||||
label: '예상 비용',
|
||||
data: [75, 69, 90, 91],
|
||||
backgroundColor: 'rgba(16, 185, 129, 0.7)',
|
||||
borderColor: 'rgba(16, 185, 129, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: { y: { beginAtZero: true, ticks: { callback: function(value) { return value + '억'; } } } },
|
||||
plugins: { legend: { display: false } }
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 내용 끝 -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- 콘텐츠 끝 -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- 페이지 컨테이너 끝 -->
|
||||
|
||||
<div id="calenderDiv" class="trViewOff" style="position:absolute;"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 페이지 로드 시 이력 목록을 불러옵니다.
|
||||
loadHistoryList();
|
||||
});
|
||||
|
||||
/**
|
||||
* 서버에 건설현장 이력 목록을 요청하는 함수
|
||||
*/
|
||||
function loadHistoryList() {
|
||||
// 알림 내역은 최신 3개만 가져오도록 설정
|
||||
var url = '/drilling/statistics/hist-list.do?page=1&rows=3';
|
||||
requesetGet(url, displayHistoryList, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 상태 코드에 따라 아이콘과 색상, 텍스트를 반환하는 함수
|
||||
*/
|
||||
function getStatusInfo(statusCode) {
|
||||
var status = {
|
||||
name: '알 수 없음',
|
||||
icon: '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>',
|
||||
bgColor: 'bg-gray-500',
|
||||
textColor: 'text-gray-600'
|
||||
};
|
||||
|
||||
switch (String(statusCode)) {
|
||||
case '0':
|
||||
status.name = '미입력';
|
||||
break;
|
||||
case '1':
|
||||
status.name = '입력 중';
|
||||
status.icon = '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.5L14.732 3.732z"></path></svg>';
|
||||
status.bgColor = 'bg-blue-500';
|
||||
status.textColor = 'text-blue-600';
|
||||
break;
|
||||
case '2':
|
||||
case '3':
|
||||
status.name = '검수중';
|
||||
status.icon = '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16l4-4m0 0l4-4m-4 4v6m0-6H8a2 2 0 00-2 2v6a2 2 0 002 2h8a2 2 0 002-2v-6a2 2 0 00-2-2h-2"></path></svg>';
|
||||
status.bgColor = 'bg-yellow-500';
|
||||
status.textColor = 'text-yellow-600';
|
||||
break;
|
||||
case '5':
|
||||
status.name = '수정 요청';
|
||||
status.icon = '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>';
|
||||
status.bgColor = 'bg-red-500';
|
||||
status.textColor = 'text-red-600';
|
||||
break;
|
||||
case '6':
|
||||
status.name = '등록 완료';
|
||||
status.icon = '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>';
|
||||
status.bgColor = 'bg-green-500';
|
||||
status.textColor = 'text-green-600';
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* API 호출 결과를 받아 화면에 이력 목록을 표시하는 콜백 함수
|
||||
*/
|
||||
function displayHistoryList(response) {
|
||||
var notificationList = document.getElementById('notification-list');
|
||||
notificationList.innerHTML = ''; // 기존 목록 초기화
|
||||
|
||||
if (response && response.resultCode === 200 && response.datas) {
|
||||
var datas = response.datas;
|
||||
var contentHtml = '';
|
||||
|
||||
for (var i = 0; i < datas.length; i++) {
|
||||
var item = datas[i];
|
||||
|
||||
var preStateInfo = getStatusInfo(item.preProjectStateCode);
|
||||
var currentStateInfo = getStatusInfo(item.projectStateCode);
|
||||
|
||||
var dateParts = item.modDt ? item.modDt.split(' ') : ['', ''];
|
||||
var ymd = dateParts[0];
|
||||
var hms = dateParts[1];
|
||||
|
||||
contentHtml +=
|
||||
'<div class="flex items-start p-2 bg-gray-50 rounded-lg">' +
|
||||
'<div class="' + currentStateInfo.bgColor + ' text-white rounded-full h-8 w-8 flex-shrink-0 flex items-center justify-center mr-3">' +
|
||||
currentStateInfo.icon +
|
||||
'</div>' +
|
||||
'<div>' +
|
||||
'<p class="text-3xl font-medium text-gray-800">\'' + item.constName + '\'</p>' +
|
||||
'<p class="text-2xl text-gray-600">' +
|
||||
'상태가 <span class="font-semibold ' + preStateInfo.textColor + '">' + preStateInfo.name + '</span>에서 ' +
|
||||
'<span class="font-semibold ' + currentStateInfo.textColor + '">' + currentStateInfo.name + '</span>으로 변경되었습니다.' +
|
||||
'</p>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
if (datas.length === 0) {
|
||||
contentHtml = '<div class="p-4 text-center text-gray-500">최근 알림 내역이 없습니다.</div>';
|
||||
}
|
||||
|
||||
notificationList.innerHTML = contentHtml;
|
||||
} else {
|
||||
notificationList.innerHTML = '<div class="p-4 text-center text-gray-500">알림 목록을 불러오는 데 실패했습니다.</div>';
|
||||
console.error("Error fetching history list:", response.resultMessage);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<%@ include file="/include/inc_footer_2021_new.jsp" %>
|
||||
|
|
@ -17,6 +17,9 @@
|
|||
<script src="${pageContext.request.contextPath}/js/jquery/jquery.min.js"
|
||||
language=javascript></script>
|
||||
|
||||
<script language=JavaScript src="${pageContext.request.contextPath}/js/common/common.js"></script>
|
||||
<script language=JavaScript src="${pageContext.request.contextPath}/js/common/myXhr.js"></script>
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width,initial-scale=1.0,maximum-scale=1" />
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
<script type="text/javascript"
|
||||
src="${pageContext.request.contextPath}/js/map/main/download.min.js"></script>
|
||||
|
||||
<input type="hidden" id="cls" name="cls" value="<c:out value="${params.cls}"/>" />
|
||||
|
||||
<script type="text/javascript"
|
||||
src="${pageContext.request.contextPath}/js/map/main/main.js?v=20250617_094801"></script>
|
||||
<script type="text/javascript"
|
||||
|
|
@ -127,6 +129,8 @@ function LoadingShow() {
|
|||
<input type="hidden" id="mapGbn" name="mapGbn" value="<c:out value="${mapGbn}"/>" />
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<!-- 페이지 컨테이너 시작 -->
|
||||
<section class="page-container">
|
||||
|
||||
|
|
@ -254,6 +258,22 @@ function LoadingShow() {
|
|||
</ul>
|
||||
</div>
|
||||
<!-- 그리기도구 끝 -->
|
||||
|
||||
<!-- 레이어 시작 -->
|
||||
<div class="map-right-control-group">
|
||||
<div class="map-right-control-title">레이어</div>
|
||||
<ul class="map-right-btn-group">
|
||||
<li>
|
||||
<a href="javascript:geologyMode();"
|
||||
class="map-right-btn map-btn-icon-geology">지질</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:geologyMine();"
|
||||
class="map-right-btn map-btn-icon-mine">광산</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 그리기도구 끝 -->
|
||||
</div>
|
||||
<!-- 지도 오른쪽 컨트롤 끝 -->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
|
||||
<link rel="stylesheet" HREF="/css/style.css" type="text/css">
|
||||
<link href="/css/hn1.css" rel="stylesheet" type="text/css">
|
||||
<script language=JavaScript src="${pageContext.request.contextPath}/js/common/myXhr.js"></script>
|
||||
<script src="${pageContext.request.contextPath}/js/map/main/left/left.js"></script>
|
||||
<script src="${pageContext.request.contextPath}/js/map/main/result.js"></script>
|
||||
<script src="/js/map/gis/lib/js/jquery-1.11.0.min.js"></script>
|
||||
|
|
@ -291,7 +292,10 @@
|
|||
<tr>
|
||||
<td><table width="100%" border=0>
|
||||
<tr>
|
||||
<td height="19" valign="top"><img src="/body/map/download/image/btn_allselect.gif" onClick="javascript:allSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand"><img src="/images/menu04/spacer.gif" width="10" height="19"><img src="/body/map/download/image/btn_deselect.gif" onClick="javascript:allDeSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand">
|
||||
<td height="19" valign="top">
|
||||
<img src="/body/map/download/image/btn_delete_all.gif" onClick="javascript:deleteAllCartList()" style="cursor: pointer">
|
||||
<img src="/images/menu04/spacer.gif" width="10" height="19">
|
||||
<img src="/body/map/download/image/btn_allselect.gif" onClick="javascript:allSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand"><img src="/images/menu04/spacer.gif" width="10" height="19"><img src="/body/map/download/image/btn_deselect.gif" onClick="javascript:allDeSelect('<c:out value='${params.cnt}'/>')" style="cursor: hand">
|
||||
<img src="/images/menu04/spacer.gif" width="10" height="19"><img src="/body/map/download/image/btn_download.gif" onClick="javascript:downloadNew('<c:out value='${params.cnt}'/>')" style="cursor: hand"></td>
|
||||
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -93,17 +93,22 @@
|
|||
<li class="dropdown simple-dropdown">
|
||||
<a href="/manage/complete.do" id="manageComplete" data-target="navbar-nav-complete">검수등록완료 목록</a>
|
||||
</li>
|
||||
<c:if test="${'admin_user' == topUserId}">
|
||||
<c:if test="${9 == cls}">
|
||||
<li class="dropdown simple-dropdown">
|
||||
<a href="/list_reg.do" id="manageRegList" data-target="navbar-nav-listReg">입력중인프로젝트 현황</a>
|
||||
</li>
|
||||
</c:if>
|
||||
<c:if test="${'admin_user' == topUserId}">
|
||||
<c:if test="${9 == cls}">
|
||||
<li class="dropdown simple-dropdown">
|
||||
<a href="/holeCoord.do" id="manageCoordinate" data-target="navbar-nav-holeCoord">좌표수정</a>
|
||||
</c:if>
|
||||
</li>
|
||||
<c:if test="${'admin_user' == topUserId}">
|
||||
<c:if test="${9 == cls}">
|
||||
<li class="dropdown simple-dropdown">
|
||||
<a href="/re-name.do" id="manageName" data-target="navbar-nav-holeCoord">프로젝트명 수정</a>
|
||||
</c:if>
|
||||
</li>
|
||||
<c:if test="${9 == cls}">
|
||||
<li class="dropdown simple-dropdown">
|
||||
<a href="/webManageAdd.do" id="manageAdd" data-target="navbar-nav-webManageAdd">검수자 관리</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -232,6 +232,9 @@ function fn_isNumeric(fieldData, fieldName, msgTest) {
|
|||
function fn_validateLength(fieldData, fieldName, msgTest, intLength, decimalLength) {
|
||||
for (let i = 0; i < fieldData.length; i++) {
|
||||
let value = fieldData[i][fieldName];
|
||||
if( value === -999 ) {
|
||||
continue;
|
||||
}
|
||||
let parts = value.toString().split(".");
|
||||
if (parts[0].length > intLength || (parts[1] && parts[1].length > decimalLength)) {
|
||||
alert(msgTest + "의 값은 정수 : " + intLength + "자리, 소수점 이하 : " + decimalLength + "자리까지 입력할 수 있습니다.");
|
||||
|
|
@ -241,14 +244,43 @@ function fn_validateLength(fieldData, fieldName, msgTest, intLength, decimalLeng
|
|||
return true;
|
||||
}
|
||||
|
||||
function changeHyphenToMinus999Main(data) {
|
||||
for( idx in data ) {
|
||||
// -(hyphen) 허용한 것을 -999로 변환한다.
|
||||
var targetItemKey = 'fieldperAvgPermeability';
|
||||
data[idx][targetItemKey] = changeHyphenToMinus999(data[idx][targetItemKey]);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function changeHyphenToMinus999Sub(data) {
|
||||
for( idx in data ) {
|
||||
// -(hyphen) 허용한 것을 -999로 변환한다.
|
||||
var targetItemKey = 'fieldperSubTotalHead';
|
||||
data[idx][targetItemKey] = changeHyphenToMinus999(data[idx][targetItemKey]);
|
||||
|
||||
targetItemKey = 'fieldperSubPermeability';
|
||||
data[idx][targetItemKey] = changeHyphenToMinus999(data[idx][targetItemKey]);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function changeHyphenToMinus999(data) {
|
||||
if( data === '-' ) {
|
||||
data = -999;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
//Data 저장.
|
||||
function fn_save(rUrl) {
|
||||
|
||||
//240103 임효주 - 현장투수시험 (평균)투수계수의 type 에러 예방. 해당 값이 숫자 또는 공백인지 확인
|
||||
let fieldData1 = kendoJQuery("#kictGrid1").data("kendoGrid")._data;
|
||||
let fieldName1 = "fieldperAvgPermeability"; // 수정됨
|
||||
let msgTest1 = "평균투수계수";
|
||||
|
||||
fieldData1 = changeHyphenToMinus999Main(fieldData1);
|
||||
if (!fn_isNumeric(fieldData1, fieldName1, msgTest1)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -256,7 +288,7 @@ function fn_save(rUrl) {
|
|||
let fieldData2 = kendoJQuery("#kictGrid2").data("kendoGrid")._data;
|
||||
let fieldName2 = "fieldperSubPermeability"; // 수정됨
|
||||
let msgTest2 = "투수계수";
|
||||
|
||||
fieldData2 = changeHyphenToMinus999Sub(fieldData2);
|
||||
if (!fn_isNumeric(fieldData2, fieldName2, msgTest2)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -339,9 +371,11 @@ function fn_save(rUrl) {
|
|||
if(fn_saveNumberCheckKendo("ROW", dataSource2, grid2, "gridCheck2", 0, rowInfo2, rowInfoItem2) == false)return false;
|
||||
|
||||
//data1
|
||||
data1 = changeHyphenToMinus999Main(data1);
|
||||
var kendoData1 = fn_kendoAllDataXml02(grid1, kendoColCount1, kendoRowCount1, 0, data1);
|
||||
|
||||
//data2
|
||||
data2 = changeHyphenToMinus999Sub(data2);
|
||||
var kendoData2 = fn_kendoAllDataXml02(grid2, kendoColCount2, kendoRowCount2, 0, data2);
|
||||
// ----------------------- kendoGrid XML 구조저장 끝 -----------------------
|
||||
|
||||
|
|
@ -887,7 +921,20 @@ function fn_grid_refresh(){
|
|||
},
|
||||
{ field: "fieldperCasingDia", title: "케이싱지름(cm)", editor: chooseEditor, width:120, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperCasingDia == null) ? '0' : fieldperCasingDia #</div>" },
|
||||
{ field: "fieldperCasingHeight", title: "케이싱길이(m)", editor: chooseEditor, width:120, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperCasingHeight == null) ? '0' : fieldperCasingHeight #</div>" },
|
||||
{ field: "fieldperAvgPermeability", title: "평균투수계수<br>(cm/sec)", editor: chooseTest, width:120, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperAvgPermeability == null) ? '0' : fieldperAvgPermeability #</div>" },
|
||||
{ field: "fieldperAvgPermeability", title: "평균투수계수<br>(cm/sec)", editor: chooseTest, width:120, attributes: { style:"text-align: right" },
|
||||
template: function(data) {
|
||||
//"<div class='td-data'>#= (fieldperAvgPermeability == null) ? '0' : fieldperAvgPermeability #</div>"
|
||||
if( data.fieldperAvgPermeability === "") {
|
||||
data.fieldperAvgPermeability = "0";
|
||||
} else if( data.fieldperAvgPermeability === null) {
|
||||
data.fieldperAvgPermeability = "0";
|
||||
} else if( data.fieldperAvgPermeability === "-999") {
|
||||
data.fieldperAvgPermeability = "-";
|
||||
}
|
||||
var url = "<div class='td-data' data-allow-hyphen='true'>" + data.fieldperAvgPermeability + "</div>";
|
||||
return url;
|
||||
}
|
||||
},
|
||||
{ field: "fieldperInspectedBy", title: "조사자", width:150, attributes: { style:"text-align: left" }, template: "<div class='td-data'>#= (fieldperInspectedBy == null) ? '-' : fieldperInspectedBy #</div>" },
|
||||
{ field: "fieldperCheckedBy", title: "검수자", width:150, attributes: { style:"text-align: left" }, template: "<div class='td-data'>#= (fieldperCheckedBy == null) ? '-' : fieldperCheckedBy #</div>" },
|
||||
{ field: "fieldperRemark", title: "비고", width:120, attributes: { style:"text-align: left" }, template: "<div class='td-data'>#= (fieldperRemark == null) ? '-' : fieldperRemark #</div>" },
|
||||
|
|
@ -962,7 +1009,7 @@ function fn_grid_refresh(){
|
|||
oldFieldperCode: { type: "string" },
|
||||
fieldperOrder: { type: "number", editable: false },
|
||||
fieldperSubTime: { type: "number" },
|
||||
fieldperSubTotalHead: { type: "number" },
|
||||
fieldperSubTotalHead: { type: "string" },
|
||||
fieldperSubFallingHead: { type: "number" },
|
||||
fieldperSubWaterLoose: { type: "number" },
|
||||
fieldperSubQuantity: { type: "number" },
|
||||
|
|
@ -977,11 +1024,37 @@ function fn_grid_refresh(){
|
|||
columns: [
|
||||
{ field: "fieldperOrder", title: "시험<br>순서", width:60, attributes: { style:"text-align: center" } },
|
||||
{ field: "fieldperSubTime", title: "시간(sec)<br/>(값 중복 허용 안 함)", editor: chooseEditor, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperSubTime == null) ? '0' : fieldperSubTime #</div>" },
|
||||
{ field: "fieldperSubTotalHead", title: "총수두(cm)", editor: chooseEditor, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperSubTotalHead == null) ? '0' : fieldperSubTotalHead #</div>" },
|
||||
{ field: "fieldperSubTotalHead", title: "총수두(cm)", editor: chooseEditorAllowHyphen, attributes: { style:"text-align: right" },
|
||||
template: function(data) {
|
||||
//"<div class='td-data'>#= (fieldperSubTotalHead == null) ? '0' : fieldperSubTotalHead #</div>"
|
||||
if( data.fieldperSubTotalHead === "") {
|
||||
data.fieldperSubTotalHead = "0";
|
||||
} else if( data.fieldperSubTotalHead === null) {
|
||||
data.fieldperSubTotalHead = "0";
|
||||
} else if( data.fieldperSubTotalHead === "-999") {
|
||||
data.fieldperSubTotalHead = "-";
|
||||
}
|
||||
var url = "<div class='td-data' data-allow-hyphen='true'>" + data.fieldperSubTotalHead + "</div>";
|
||||
return url;
|
||||
}
|
||||
},
|
||||
{ field: "fieldperSubFallingHead", title: "수두차(cm)", editor: chooseEditor, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperSubFallingHead == null) ? '0' : fieldperSubFallingHead #</div>" },
|
||||
{ field: "fieldperSubWaterLoose", title: "유출수량(㎤)", editor: chooseEditor, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperSubWaterLoose == null) ? '0' : fieldperSubWaterLoose #</div>" },
|
||||
{ field: "fieldperSubQuantity", title: "수량(㎤)", editor: chooseEditor, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperSubQuantity == null) ? '0' : fieldperSubQuantity #</div>" },
|
||||
{ field: "fieldperSubPermeability", title: "투수계수(K,cm/sec)", editor: chooseTest, attributes: { style:"text-align: right" }, template: "<div class='td-data'>#= (fieldperSubPermeability == null) ? '0' : fieldperSubPermeability #</div>" },
|
||||
{ field: "fieldperSubPermeability", title: "투수계수(K,cm/sec)", editor: chooseTest, attributes: { style:"text-align: right" },
|
||||
template: function(data) {
|
||||
//"<div class='td-data'>#= (fieldperSubPermeability == null) ? '0' : fieldperSubPermeability #</div>"
|
||||
if( data.fieldperSubPermeability === "") {
|
||||
data.fieldperSubPermeability = "0";
|
||||
} else if( data.fieldperSubPermeability === null) {
|
||||
data.fieldperSubPermeability = "0";
|
||||
} else if( data.fieldperSubPermeability === "-999") {
|
||||
data.fieldperSubPermeability = "-";
|
||||
}
|
||||
var url = "<div class='td-data' data-allow-hyphen='true'>" + data.fieldperSubPermeability + "</div>";
|
||||
return url;
|
||||
}
|
||||
},
|
||||
{ field: "seq", hidden: true },
|
||||
{ field: "newFieldperCode", hidden: true },
|
||||
{ field: "oldFieldperCode", hidden: true },
|
||||
|
|
@ -1041,6 +1114,14 @@ function fn_grid_refresh(){
|
|||
}
|
||||
}
|
||||
|
||||
function chooseEditorAllowHyphen(container, options) {
|
||||
switch (options.model.COLUMN) {
|
||||
default:
|
||||
numericEditorAllowHyphen(container, options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function chooseTest(container, options) {
|
||||
|
||||
switch (options.model.COLUMN) {
|
||||
|
|
|
|||
|
|
@ -125,10 +125,10 @@ function fn_help_tour(){
|
|||
<tr>
|
||||
<th class="td-head">시추공 고유번호</th>
|
||||
<th class="td-head">시추공명</th>
|
||||
<th class="td-head">원좌표_X</th>
|
||||
<th class="td-head">원좌표_Y</th>
|
||||
<th class="td-head">경도</th>
|
||||
<th class="td-head">위도</th>
|
||||
<th class="td-head">좌표계번호</th>
|
||||
<th class="td-head">원좌표_X(E)</th>
|
||||
<th class="td-head">원좌표_Y(N)</th>
|
||||
<th class="td-head">지도</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -141,17 +141,39 @@ function fn_help_tour(){
|
|||
<td class="td-head">
|
||||
${result.holeName}
|
||||
</td>
|
||||
<td class="td-head">
|
||||
<select name="language" >
|
||||
<option value="32651">32651</option>
|
||||
<option value="32652">32652</option>
|
||||
<option value="4004">4004</option>
|
||||
<option value="4019">4019</option>
|
||||
<option value="4326">4326</option>
|
||||
<option value="5173">5173</option>
|
||||
<option value="5174">5174</option>
|
||||
<option value="5176">5176</option>
|
||||
<option value="5177">5177</option>
|
||||
<option value="5179">5179</option>
|
||||
<option value="5180">5180</option>
|
||||
<option value="5181">5181</option>
|
||||
<option value="5183">5183</option>
|
||||
<option value="5184" selected>5184</option>
|
||||
<option value="5185">5185</option>
|
||||
<option value="5186">5186</option>
|
||||
<option value="5187">5187</option>
|
||||
<option value="5188">5188</option>
|
||||
<option value="5190">5190</option>
|
||||
<option value="5191">5191</option>
|
||||
<option value="5192">5192</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="HOLE_OR_X_${status.count}" name="HOLE_OR_X_${status.count}" value="${result.holeOrX}" />
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="HOLE_OR_Y_${status.count}" name="HOLE_OR_Y_${status.count}" value="${result.holeOrY}" />
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="HOLE_LOCATION_X_${status.count}" name="HOLE_LOCATION_X_${status.count}" value="${result.holeLocationX}" />
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="HOLE_LOCATION_Y_${status.count}" name="HOLE_LOCATION_Y_${status.count}" value="${result.holeLocationY}" />
|
||||
<td style="text-align: center;">
|
||||
<button class="btn btn-primary" type="button">지도</button>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
|
|
|
|||
|
|
@ -8,13 +8,6 @@
|
|||
|
||||
<!--function 정의 -->
|
||||
<script type="text/javascript">
|
||||
let xhr;
|
||||
if(window.XMLHttpRequest) {
|
||||
xhr = new XMLHttpRequest();
|
||||
} else {
|
||||
// IE5, IE6 일때
|
||||
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
|
||||
var gridData = new Array(); //데이터 배열객체
|
||||
var dataList;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
|
||||
|
||||
<%@ include file="/include/inc_head_2021_new.jsp" %>
|
||||
|
||||
<!-- 자바스크립트 데이터 배열 생성 -->
|
||||
<c:import url="/includeDataArray.do" />
|
||||
|
||||
<!--function 정의 -->
|
||||
<script type="text/javascript">
|
||||
|
||||
var gridData = new Array(); //데이터 배열객체
|
||||
|
||||
//조회
|
||||
function fn_Search(){
|
||||
//날짜 체크
|
||||
if(!fn_fromToCheckAlert($("#startDate").val(), $("#endDate").val(), "기간시작일", "기간종료일", "startDate"))return false;
|
||||
|
||||
document.frmSearch.submit();
|
||||
}
|
||||
|
||||
//load
|
||||
function fn_onload(){
|
||||
|
||||
}
|
||||
|
||||
//삭제, 등록
|
||||
function fn_submit(report_type, project_code, proc){
|
||||
window.location.replace("/holeDataUpdate.do");
|
||||
}
|
||||
|
||||
//엔터키 이벤트
|
||||
function submitEvent(){
|
||||
if (event.keyCode == 13) {
|
||||
document.frmSearch.submit();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================//
|
||||
|
||||
|
||||
function fn_gourl(project_code){
|
||||
var urlStrCH = "/re-name-modify.do";
|
||||
var urlStrParam = "?&PROJECT_CODE="+project_code;
|
||||
location.href = urlStrCH+urlStrParam;
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
fn_MakeDataArray();
|
||||
kendoGrid();
|
||||
});
|
||||
|
||||
//등록 및 유통자료 생성 버튼
|
||||
function insBtnTemplate(report_type, project_code, checkuserid, expertFile, ins) {
|
||||
if ( ins == "insert" ) {
|
||||
return '<button type="button" class="k-button k-button-ins popup_open" onclick="insBtnClick('+"'"+report_type+"','"+project_code+"','"+checkuserid+"','"+expertFile+"'"+');">등록</button>'
|
||||
} else {
|
||||
return " "
|
||||
}
|
||||
}
|
||||
//등록 및 유통자료 생성 클릭
|
||||
function insBtnClick(reportType, projectCode, createUserid, expertFile) {
|
||||
/* if("admin_user"=="${LoginUserId}" || checkuserid == "${LoginUserId}"){ */ //사용자체크
|
||||
if("9"=="${cls}" || createUserid == "${loginUserId}"){ //사용자체크
|
||||
if(confirm("재등록 하여 유통자료 재생성 하시겠습니까? ")){
|
||||
|
||||
fn_submit(reportType, projectCode, 'CREATE');
|
||||
|
||||
}
|
||||
}else{
|
||||
alert("해당 검수자가 아닙니다.");
|
||||
}
|
||||
}
|
||||
|
||||
// kendoUI Grid 설정
|
||||
function onDataBound(e) {
|
||||
var grid = kendoJQuery("#grid_type_1").data("kendoGrid");
|
||||
var rows = this.items();
|
||||
|
||||
// 순번
|
||||
kendoJQuery(rows).each(function () {
|
||||
var noIndex = kendoJQuery(this).index() + 1 + (grid.dataSource.pageSize() * (grid.dataSource.page() - 1));
|
||||
var rowLabel = kendoJQuery(this).find(".row-number");
|
||||
$(rowLabel).html(noIndex);
|
||||
});
|
||||
}
|
||||
|
||||
function kendoGrid() {
|
||||
kendoJQuery("#grid_type_1").kendoGrid({
|
||||
dataSource: gridData,
|
||||
columns: [
|
||||
{ field: "rowNumber", width: 50, title: "순번", template: "<span class='row-number'></span>" },
|
||||
{
|
||||
field: "projectName",
|
||||
width: 262,
|
||||
title: "프로젝트명",
|
||||
template: function(data){
|
||||
var param = "'"+data.projectCode+"'";
|
||||
var url = "<a href=javascript:fn_gourl(" + param +");>" + data.projectName + "</a>";
|
||||
return url;
|
||||
},
|
||||
attributes: { style:"text-align: left" }
|
||||
},
|
||||
{
|
||||
field: "userName",
|
||||
width: 80,
|
||||
title: "공급자",
|
||||
template: function(data){
|
||||
var param = "'"+data.userid+"'";
|
||||
var url = "<a href=javascript:fn_ProviderInfoPopupDiv("+ param +",'ProviderInfo');>" + data.userName + "</a>";
|
||||
return url;
|
||||
},
|
||||
},
|
||||
{ field: "datetime", width: 130, title: "입력일시", template: "<div class='td-data'>#: datetime #</div>" },
|
||||
{ field: "stateName", width: 80, title: "공급현황", template: "<div class='td-data'>#: stateName #</div>" },
|
||||
{
|
||||
field: "createName",
|
||||
width: 80,
|
||||
title: "등록자",
|
||||
template: function(data){
|
||||
var param = "'"+data.createUserid+"'";
|
||||
var url = "<a href=javascript:fn_ProviderInfoPopupDiv("+ param +",'ProviderInfo');>" + data.createName + "</a>";
|
||||
return url;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: "ins",
|
||||
width: 60, title: "재등록",
|
||||
template: "<div class='td-data'>#= insBtnTemplate(data.reportType, data.projectCode, data.createUserid, data.expertFile, data.ins) #</div>"
|
||||
},
|
||||
],
|
||||
sortable: true,
|
||||
scrollable: true,
|
||||
selectable: true,
|
||||
columnResizeHandleWidth: 20,
|
||||
resizable: true,
|
||||
pageable: {
|
||||
refresh: false,
|
||||
pageSizes: true,
|
||||
pageSize: 10,
|
||||
//buttonCount: 10,
|
||||
input: true,
|
||||
numeric: false,
|
||||
},
|
||||
noRecords: {
|
||||
template: "등록된데이터가 없습니다."
|
||||
},
|
||||
dataBound: onDataBound,
|
||||
});
|
||||
}
|
||||
|
||||
/* 도움말 시작 */
|
||||
function fn_help_tour(){
|
||||
var pageTitle = "프로젝트명 수정 목록";
|
||||
iGuider({
|
||||
tourTitle: pageTitle,
|
||||
intro:{
|
||||
title: pageTitle + ' 조회 방법이 궁금하신가요?',
|
||||
content: pageTitle + ' 조회 방법 사용설명을 진행하겠습니다.'
|
||||
},
|
||||
steps:[{
|
||||
title:'Step 1',
|
||||
content: pageTitle +'을 사업명, 공급자, 등록자로 상세 검색을 할 수 있습니다.',
|
||||
target:'project-search'
|
||||
},{
|
||||
title:'Step 2',
|
||||
content: pageTitle +'의 목록이 조회되며 프로젝트명을 클릭하면 프로젝트명을 수정 할 수 있습니다.',
|
||||
target:'grid'
|
||||
}],
|
||||
// 중단
|
||||
abort: function(){
|
||||
fn_grid_refresh();
|
||||
},
|
||||
// 끝
|
||||
end: function(){
|
||||
fn_grid_refresh();
|
||||
},
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 도움말이 끝나면 kendoGrid의 이벤트가 중단되기 때문에 iGuider의 모든 효과를 제거를 해주고 kendoGrid를 다시 실행
|
||||
function fn_grid_refresh(){
|
||||
// iGuider의 모든 효과를 제거
|
||||
iGuider('destroy');
|
||||
|
||||
// 그리드 refresh
|
||||
var grid = kendoJQuery("#grid_type_1").data("kendoGrid");
|
||||
grid.refresh();
|
||||
|
||||
}
|
||||
/* 도움말 끝 */
|
||||
|
||||
</script>
|
||||
|
||||
<!-- header start-->
|
||||
<c:import url="/manage/includeTopInput.do" charEncoding="UTF-8" />
|
||||
<!-- header end-->
|
||||
|
||||
<!-- 페이지 컨테이너 시작 -->
|
||||
<section class="page-container">
|
||||
|
||||
<div class="page-content-wrapper">
|
||||
|
||||
<!-- left start-->
|
||||
<c:import url="/manage/includeLeftInput.do" charEncoding="UTF-8" />
|
||||
<!-- left end-->
|
||||
|
||||
<!-- 컨텐츠 시작 -->
|
||||
<div class="page-content">
|
||||
|
||||
<div class="page-content-inner">
|
||||
|
||||
<!-- 카테고리 시작 -->
|
||||
<div class="category-wrapper">
|
||||
<ul class="page-category">
|
||||
<li class="category-item" id="category_1dep"></li>
|
||||
<li class="category-item">프로젝트명 수정 목록</li>
|
||||
</ul>
|
||||
<a href="javascript:;" class="btn btn-help start-tour" onClick="fn_help_tour();">도움말</a>
|
||||
</div>
|
||||
|
||||
<!-- 카테고리 끝 -->
|
||||
|
||||
<h1 class="page-title-1depth"><span>프로젝트명 수정 목록</span></h1>
|
||||
|
||||
<!-- 내용 시작 -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- search start -->
|
||||
<div class="contents">
|
||||
|
||||
<!-- 검색영역 시작 -->
|
||||
<div class="page-top-search" data-target="project-search">
|
||||
<form name="frmSearch" id="frmSearch" action="holeCoord.do" method="post">
|
||||
|
||||
<div class="form-inline row">
|
||||
<div class="input-group col-md-4 col-xs-4 col-sm-4">
|
||||
<label class="input-label-display" for="searchProjectName">사업명</label>
|
||||
<input id="searchProjectName" name="searchProjectName" type="text" value="${searchProjectName}" maxlength="50" onKeyPress="submitEvent()"/>
|
||||
</div>
|
||||
<div class="input-group col-md-4 col-xs-4 col-sm-4">
|
||||
<label class="input-label-display" for="searchUserName">공급자</label>
|
||||
<input id="searchUserName" name="searchUserName" type="text" value="${searchUserName}" maxlength="50" onKeyPress="submitEvent()"/>
|
||||
</div>
|
||||
<div class="input-group col-md-4 col-xs-4 col-sm-4">
|
||||
<label class="input-label-display" for="searchCreateName">등록자</label>
|
||||
<input id="searchCreateName" name="searchCreateName" type="text" value="${searchCreateName}" maxlength="50" onKeyPress="submitEvent()"/>
|
||||
<span class="input-group-btn input-group-last">
|
||||
<button type="button" class="btn btn-ske-blue btn-icon-left btn-icon-search" onClick="fn_Search()" onKeyPress="submitEvent()"><span>조회</span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<!-- 검색영역 끝 -->
|
||||
|
||||
<!-- kendoUI grid start -->
|
||||
<%@ include file="/include/inc_kendoUI_2019.jsp" %>
|
||||
<div id="grid_type_1" class="kist-grid" data-target="grid"></div>
|
||||
<!-- kendoUI grid end -->
|
||||
|
||||
</div>
|
||||
<!-- search end -->
|
||||
|
||||
</div>
|
||||
<!-- 내용 끝 -->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 컨텐츠 끝 -->
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<!-- 페이지 컨테이너 끝 -->
|
||||
|
||||
<!-- footer 시작 -->
|
||||
<%@ include file="/include/inc_footer_2021_new.jsp" %>
|
||||
<!-- footer 끝 -->
|
||||
|
||||
<div id="ProviderInfo" class="trViewOff" style="position:absolute;"></div>
|
||||
<div id="progressbarDiv" class="trViewOff" style="position:absolute;z-index:999;"></div>
|
||||
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
|
||||
|
||||
<%@ include file="/include/inc_head_2021_new.jsp" %>
|
||||
|
||||
<!--function 정의 -->
|
||||
<script type="text/javascript">
|
||||
|
||||
//load
|
||||
function fn_onload(){
|
||||
|
||||
}
|
||||
|
||||
//삭제, 등록
|
||||
function fn_submit(report_type, project_code, proc){
|
||||
window.location.replace("list_db.jsp?REPORT_TYPE="+report_type+"&PROJECT_CODE="+project_code+"&PROC="+proc);
|
||||
}
|
||||
|
||||
function fn_save(){
|
||||
document.frmCoor.submit();
|
||||
}
|
||||
|
||||
/* 도움말 시작 */
|
||||
function fn_help_tour(){
|
||||
var pageTitle = "프로젝트명 수정";
|
||||
iGuider({
|
||||
tourTitle: pageTitle,
|
||||
intro:{
|
||||
title: pageTitle + ' 입력 방법이 궁금하신가요?',
|
||||
content: pageTitle + ' 입력 방법 사용설명을 진행하겠습니다.'
|
||||
},
|
||||
steps:[{
|
||||
title:'Step 1',
|
||||
content: pageTitle +'프로젝트 명을 확인합니다.',
|
||||
target:'project-info-name'
|
||||
},{
|
||||
title:'Step 2',
|
||||
content: '모두 수정하였다면 저장버튼을 클릭하며 저장 합니다.',
|
||||
target:'form-save'
|
||||
}]
|
||||
});
|
||||
return false;
|
||||
}
|
||||
/* 도움말 끝 */
|
||||
|
||||
</script>
|
||||
|
||||
<!-- header start-->
|
||||
<c:import url="/manage/includeTopInput.do" charEncoding="UTF-8" />
|
||||
<!-- header end-->
|
||||
|
||||
<!-- 페이지 컨테이너 시작 -->
|
||||
<section class="page-container">
|
||||
|
||||
<div class="page-content-wrapper">
|
||||
|
||||
<!-- left start-->
|
||||
<c:import url="/manage/includeLeftInput.do" charEncoding="UTF-8" />
|
||||
<!-- left end-->
|
||||
|
||||
<!-- 컨텐츠 시작 -->
|
||||
<div class="page-content">
|
||||
|
||||
<div class="page-content-inner">
|
||||
|
||||
<!-- 카테고리 시작 -->
|
||||
<div class="category-wrapper">
|
||||
<ul class="page-category">
|
||||
<li class="category-item" id="category_1dep"></li>
|
||||
<li class="category-item">프로젝트명 수정</li>
|
||||
</ul>
|
||||
<a href="javascript:;" class="btn btn-help start-tour" onClick="fn_help_tour();">도움말</a>
|
||||
</div>
|
||||
|
||||
<!-- 카테고리 끝 -->
|
||||
|
||||
<h1 class="page-title-1depth"><span>프로젝트명 수정</span></h1>
|
||||
|
||||
<!-- 내용 시작 -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- search start -->
|
||||
<div class="contents">
|
||||
<div class="table-scrollable content-info-table" data-target="project-info">
|
||||
<table class="table table-bordered">
|
||||
<colgroup>
|
||||
<col style="width:160px;">
|
||||
<col style="width:auto;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr data-target="project-info-name">
|
||||
<th class="td-head">프로젝트 명</th>
|
||||
<td>${pName}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="table-top-control">
|
||||
<div class="table-btn-group">
|
||||
<button type="button" class="btn btn-small btn-rounded5 btn-ske-blue btn-icon-left btn-icon-save" data-target="form-save" onClick="fn_save(); return false;"><span>저장</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form name="frmCoor" id="frmCoor" action="/holeCoordUpdate.do" method="post">
|
||||
<input type="hidden" id="PROC" name="PROC" value="MODIFY" />
|
||||
<input type="hidden" id="PROJECT_CODE" name="PROJECT_CODE" value="${projectCode}" />
|
||||
<input type="hidden" id="rowCnt" name="rowCnt" value="${fn:length(result)}" />
|
||||
<div class="table-scrollable" data-target="grid">
|
||||
<table class="table table-bordered">
|
||||
<colgroup>
|
||||
<col style="width:auto;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td-head">변경할 프로젝트명</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" id="re-name" name="re-name" value="${pName}" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- search end -->
|
||||
|
||||
</div>
|
||||
<!-- 내용 끝 -->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 컨텐츠 끝 -->
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<!-- 페이지 컨테이너 끝 -->
|
||||
|
||||
<!-- footer 시작 -->
|
||||
<%@ include file="/include/inc_footer_2021_new.jsp" %>
|
||||
<!-- footer 끝 -->
|
||||
|
||||
<div id="ProviderInfo" class="trViewOff" style="position:absolute;"></div>
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link href="/js/map/gis/css/map.css" rel="stylesheet"/>
|
||||
|
||||
|
||||
<title>지도</title>
|
||||
</head>
|
||||
<body onload="initMap();">
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
<filter-name>encodingFilter</filter-name>
|
||||
<url-pattern>*.do</url-pattern>
|
||||
<url-pattern>*.json</url-pattern>
|
||||
<url-pattern>/video/stream/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<!-- 멀티파트필터 적용 -->
|
||||
|
|
@ -74,6 +75,10 @@
|
|||
<servlet-name>action</servlet-name>
|
||||
<url-pattern>*.json</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>action</servlet-name>
|
||||
<url-pattern>/video/stream/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet>
|
||||
<servlet-name>ImageServlet</servlet-name>
|
||||
<servlet-class>net.sf.jasperreports.j2ee.servlets.ImageServlet</servlet-class>
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -863,6 +863,13 @@ header .global-link-wrapper {
|
|||
background: url(../img/map-service/icon/ico_map_right_control_19.png) no-repeat 50% 50%;
|
||||
}
|
||||
|
||||
.map-right-btn-group > li .map-right-btn.map-btn-icon-geology::before {
|
||||
background: url(../img/map-service/icon/ico_map_right_control_geology.png) no-repeat 50% 50%;
|
||||
}
|
||||
.map-right-btn-group > li .map-right-btn.map-btn-icon-mine::before {
|
||||
background: url(../img/map-service/icon/ico_map_right_control_mine.png) no-repeat 50% 50%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 지도구분 탭 시작 */
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -1,11 +1,3 @@
|
|||
let xhr;
|
||||
if(window.XMLHttpRequest) {
|
||||
xhr = new XMLHttpRequest();
|
||||
} else {
|
||||
// IE5, IE6 일때
|
||||
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
|
||||
function onClickBtnViewOnMap() {
|
||||
const projectMasterCompanyName = '${mbr.projectMasterCompanyName}';
|
||||
let projectCode = '${mbr.ProjectCode}';
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
============================================================== -->
|
||||
<!-- <link rel="stylesheet" href="/web/css/common.css"/> -->
|
||||
<script type="text/javaScript" src="/web/js/common.js"></script>
|
||||
<script language=JavaScript src="${pageContext.request.contextPath}/js/common/myXhr.js"></script>
|
||||
|
||||
<!-- ==============================================================
|
||||
공통 커스텀
|
||||
|
|
|
|||
|
|
@ -0,0 +1,172 @@
|
|||
let xhr;
|
||||
if(window.XMLHttpRequest) {
|
||||
xhr = new XMLHttpRequest();
|
||||
} else {
|
||||
// IE5, IE6 일때
|
||||
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
|
||||
function requesetGet(URL, callback, callbackParamAsJson) {
|
||||
xhr.open('GET', URL, true);
|
||||
xhr.setRequestHeader('Content-type', 'application/json');
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
var obj = JSON.parse(xhr.responseText);
|
||||
if (typeof callback === 'function') {
|
||||
callback(obj, callbackParamAsJson);
|
||||
}
|
||||
} else if (xhr.readyState === 4) {
|
||||
// 요청 실패 시 처리
|
||||
console.error('요청 실패:', xhr.status);
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
function requesetPost(URL, jsonData, callback, callbackParamAsJson) {
|
||||
xhr.open('POST', URL, true);
|
||||
xhr.setRequestHeader('Content-type', 'application/json');
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
// 요청 성공 시 처리
|
||||
let result = JSON.parse(xhr.response);
|
||||
console.log(result.resultCode)
|
||||
console.log(xhr.responseText);
|
||||
const obj = JSON.parse(xhr.responseText);
|
||||
if( typeof callback !== 'undefined' ) {
|
||||
callback(callbackParamAsJson);
|
||||
}
|
||||
if (obj.resultCode == 100) {
|
||||
} else {
|
||||
//alert(obj.message);
|
||||
}
|
||||
} else if (xhr.readyState === 4) {
|
||||
// 요청 실패 시 처리
|
||||
console.error('요청 실패:', xhr.status);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(JSON.stringify(jsonData));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* AJAX
|
||||
*/
|
||||
|
||||
//일반적인 경우
|
||||
function ajax(url, param, callback){
|
||||
$.ajax({
|
||||
'type': 'POST',
|
||||
url: url,
|
||||
// async: false, //전역변수 한것(일단 추가했음- 삭제가능)
|
||||
data: param,
|
||||
// success:eval(callback),
|
||||
success:function(data){
|
||||
eval(callback)(data);
|
||||
},
|
||||
error: function(xhr, status, error){
|
||||
alert("error :ajax status:"+xhr.status+"\nerror:"+error+"\nerror message:"+xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//파일첨부용
|
||||
function ajaxSubmit(formId,url,param,callback){
|
||||
eval($(formId)).ajaxSubmit({
|
||||
url: url,
|
||||
data: param,
|
||||
success:eval(callback),
|
||||
error: function(xhr, status, error){
|
||||
alert("예외발생가 발생했습니다. 시스템관리자에게 확인바랍니다.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//폼 서브밋
|
||||
function formSubmit(formId) {
|
||||
this.formId = isNull(formId) == true ? "commonForm" : formId;
|
||||
this.url = "";
|
||||
|
||||
if(this.formId == "commonForm"){
|
||||
$("#commonForm")[0].reset();
|
||||
}
|
||||
|
||||
this.setUrl = function setUrl(url){
|
||||
this.url = url;
|
||||
};
|
||||
|
||||
this.addParam = function addParam(key, value){
|
||||
$("#"+this.formId).append($("<input type='hidden' name='"+key+"' id='"+key+"' value='"+value+"' >"));
|
||||
};
|
||||
|
||||
this.submit = function submit(){
|
||||
var frm = $("#"+this.formId)[0];
|
||||
frm.action = this.url;
|
||||
frm.method = "post";
|
||||
frm.submit();
|
||||
};
|
||||
}
|
||||
|
||||
//널값 검사
|
||||
function isNull(str) {
|
||||
if (str == null) return true;
|
||||
if (str == "NaN") return true;
|
||||
if (new String(str).valueOf() == "undefined") return true;
|
||||
var chkStr = new String(str);
|
||||
if( chkStr.valueOf() == "undefined" ) return true;
|
||||
if (chkStr == null) return true;
|
||||
if (chkStr.toString().length == 0 ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//브라우저 체크
|
||||
function fnGetBrowser() {
|
||||
var agt = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (agt.indexOf("trident") != -1) {
|
||||
return getIEVersion(agt); //'Internet Explorer';
|
||||
}
|
||||
if (agt.indexOf("chrome") != -1) return 'chrome';
|
||||
if (agt.indexOf("opera") != -1) return 'opera';
|
||||
if (agt.indexOf("firefox") != -1) return 'firefox';
|
||||
if (agt.indexOf("safari") != -1) return 'safari';
|
||||
|
||||
}
|
||||
//IE버전체크
|
||||
function getIEVersion(agt) {
|
||||
var iever="ie11";
|
||||
var index = agt.indexOf("trident");
|
||||
var len = "trident".length;
|
||||
var ver =agt.substr(index+len+1,1);
|
||||
|
||||
//IE 8 = trident/4.0
|
||||
//IE 9 = trident/5.0
|
||||
//IE 10 = trident/6.0
|
||||
if(ver==4) iever="ie8";
|
||||
if(ver==5) iever="ie9";
|
||||
if(ver==6) iever="ie10";
|
||||
if(ver==7) iever="ie11";
|
||||
|
||||
return iever;
|
||||
}
|
||||
|
||||
|
||||
String.prototype.endsWith = function(str) {
|
||||
if (this.length < str.length) { return false; }
|
||||
return this.lastIndexOf(str) + str.length == this.length;
|
||||
}
|
||||
|
||||
function XSSCheck(str, level) {
|
||||
if (level == undefined || level == 0) {
|
||||
str = str.replace(/\<|\>|\"|\'|\%|\;|\(|\)|\&|\+|\-/g,"");
|
||||
} else if (level != undefined && level == 1) {
|
||||
str = str.replace(/\</g, "<");
|
||||
str = str.replace(/\>/g, ">");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -67,6 +67,19 @@ function download(mId, fName) {
|
|||
downloadWin.focus();
|
||||
}
|
||||
|
||||
/** 장바구니 전체 데이터 삭제 * */
|
||||
function deleteAllCartList() {
|
||||
var callback = function() {
|
||||
alert('장바구니의 모든 항목이 삭제되었습니다.');
|
||||
location.reload();
|
||||
};
|
||||
if(confirm("장바구니의 모든 항목을 초기화하시겠습니까?")){
|
||||
requesetPost('/map/delete-all-cart-list.do', null, callback, null);
|
||||
}else{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** 데이터 전체 선택 * */
|
||||
function allSelect(totalCnt) {
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue