feat: 건설관리 입력 시, 발주기관 정보 자동 완성되도록 기능 수정

main
thkim 2026-02-06 16:34:18 +09:00
parent 0227785269
commit 2c6b2fcf39
14 changed files with 183 additions and 101 deletions

View File

@ -43,10 +43,12 @@ public class DrillingCommonController {
Map<String, Object> map = new HashMap<String, Object>();
map.put("userid", String.valueOf(request.getSession().getAttribute("USERID")));
// map.put("userid", String.valueOf(request.getSession().getAttribute("USERID")));
try {
Map<String, Object> result = loginService.selectWebMemberIn(map);
model.put("masterCompanyCode", result.get("master_company_code"));
model.put("partName", result.get("part_name"));
model.put("phone", result.get("phone"));
} catch (Exception e) {
model.put("errorMessage", "계정이 존재하지 않습니다");
return "/error";

View File

@ -60,7 +60,7 @@ public class DrillingInputServiceImpl implements DrillingInputService {
String projectMasterCompanyName = loginMapper.findProjectMasterCompanyNameByUserid(userId);
if( projectMasterCompanyName == null ) {
throw new Exception( "발주 기관 계정에 설정된 기관이 존재하지 않습니다" );
throw new Exception( "발주 기관 계정에 설정된 기관이 존재하지 않습니다. 로그인이 해제된 것으로 추측됩니다." );
}
HashMap<String, Object> spGetMasterCompanyDistrictParams = new HashMap<String, Object>();
@ -143,11 +143,33 @@ public class DrillingInputServiceImpl implements DrillingInputService {
@Override
public List<EgovMap> selectConstructCompanyList(HashMap<String, Object> params) throws Exception {
long start = System.currentTimeMillis();
List<EgovMap> list = new ArrayList<EgovMap>();
String companyName = MyUtil.getStringFromObject(params.get("companyName"));
if (companyName == null || companyName.isEmpty()) {
return list;
}
companyName = companyName.trim();
// 1. 자음/모음만 있는 불완전한 한글(ㄱ~ㅎ, ㅏ~ㅣ)이 포함되어 있는지 체크
if (companyName.matches(".*[ㄱ-ㅎㅏ-ㅣ].*") && !companyName.matches(".*[가-힣].*")) {
return list; // 검색을 수행하지 않고 즉시 반환
}
// 2. 너무 흔한 단어 단독 검색 차단
if (companyName.equals("(주)") || companyName.equals("주식회사")) {
return list;
}
String escapedName = companyName.replaceAll("^\\(.*?\\)", "");
escapedName = escapedName.replaceAll("\\(.*?\\)$", "");
escapedName = escapedName.replaceAll("\\(.*?\\).*", "");
//String escapedName = companyName.replace("(", "\\(").replace(")", "\\)");
params.put("companyName", escapedName);
list = drillingInputMapper.selectConstructCompanyList(params);
long end = System.currentTimeMillis();
LOGGER.info("( SERVICE ) selectConstructCompanyList 실행시간: {} ms", (end - start));
return list;
}

View File

@ -397,7 +397,7 @@ public class DrillingInquiryController {
sb.append(s(row.get("masterCompanyDept"))).append(",");
sb.append(s(row.get("masterCompanyAdmin"))).append(",");
sb.append(s(row.get("masterCompanyTel"))).append(",");
sb.append(s(row.get("coinstCompanyDept"))).append(",");
sb.append(s(row.get("constCompanyDept"))).append(",");
sb.append(s(row.get("constCompanyAdmin"))).append(",");
sb.append(s(row.get("constCompanyTel"))).append("\n");
}

View File

@ -154,8 +154,8 @@ public class DrillingInquiryServiceImpl implements DrillingInquiryService {
Long nConstCompanyCodeKey = MyUtil.getLongFromObject(data.get(constCompanyCodeKey));
if( nConstCompanyCodeKey != null ) {
params.put(constCompanyCodeKey, nConstCompanyCodeKey);
String coinstCompanyDept = drillingInquiryMapper.spGetConstCompanyName(nConstCompanyCodeKey);
data.put("coinstCompanyDept", coinstCompanyDept);
String constCompanyDept = drillingInquiryMapper.spGetConstCompanyName(nConstCompanyCodeKey);
data.put("constCompanyDept", constCompanyDept);
}

View File

@ -28,7 +28,7 @@ public final class MyUtil {
private static final Logger logger = LoggerFactory.getLogger(MyUtil.class);
public static final String VERSION = "20240816_1430";
public static final String VERSION = "20260206_1430";
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");

View File

@ -75,7 +75,8 @@
TRIM(wmi.COMPANY_NAME) AS COMPANY_NAME,
wmi.USERID,
TRIM(wmi.PART_NAME) AS PART_NAME,
wmi.EMAIL
wmi.EMAIL,
wmi.USER_NAME
FROM
web_member_in wmi
WHERE

View File

@ -21,6 +21,11 @@
<input type="hidden" id="mbr-v-max-x" name="mbr-v-max-x" value="<c:out value="${mbr.v_max_x}"/>" />
<input type="hidden" id="mbr-v-min-y" name="mbr-v-min-y" value="<c:out value="${mbr.v_min_y}"/>" />
<input type="hidden" id="mbr-v-max-y" name="mbr-v-max-y" value="<c:out value="${mbr.v_max_y}"/>" />
<input type="hidden" id="gnb-user-name" name="gnb-user-name" value="<c:out value="${userName}"/>" />
<input type="hidden" id="gnb-cls" name="gnb-cls" value="<c:out value="${cls}"/>" />
<input type="hidden" id="gnb-company-name" name="gnb-company-name" value="<c:out value="${companyName}"/>" />
<input type="hidden" id="gnb-part-name" name="gnb-part-name" value="<c:out value="${partName}"/>" />
<input type="hidden" id="gnb-phone" name="gnb-phone" value="<c:out value="${phone}"/>" />
<!-- header -------------------------------------------->

View File

@ -220,74 +220,78 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
function addItem() {
tableId += 1;
var newTable = `
<div class="table-scrollable" data-index="` + tableId + `" data-` + tableId + `>
<table class="table-bordered table-data" data-index="` + tableId + `">
<colgroup>
<col style="width: 15%;">
<col style="width: 35%;">
<col style="width: 15%;">
<col style="width: 35%;">
</colgroup>
<tbody>
<tr>
<th>사업명</th>
<td colspan="3">
<input type="text" value="" onfocusout="duplicateCheckProjectNameLocal(this)" class="input-box" id="const-name-` + tableId + `" placeholder="사업명">
</td>
</tr>
<tr>
<th>사업기간</th>
<td>
<input type="date" value="` + getToday() + `" class="date" id="const-start-date-` + tableId + `">
<span>~</span>
<input type="date" value="` + getToday() + `" class="date date-2" id="const-end-date-` + tableId + `">
</td>
<th>사업단계</th>
<td>
<select class="selectbox" id="const-state-code-` + tableId + `">
<option disabled>사업단계선택</option>
<option selected value="1">타당성조사 및 계획검토</option>
<option value="2">기본설계</option>
<option value="3">실시설계</option>
<option value="4">시공중</option>
<option value="5">준공</option>
<option value="6">유지보수</option>
</select>
</td>
</tr>
<tr>
<th>발주기관</th>
<td colspan="3">
<input type="text" class="input-box information1" id="master-company-dept-` + tableId + `" placeholder="담당부서">
<input type="text" value="홍길동" class="input-box information2" id="master-company-admin-` + tableId + `" placeholder="담당자">
<input type="text" value="02-0000-0000" class="input-box information3" id="master-company-tel-` + tableId + `" placeholder="담당자 연락처">
</td>
</tr>
<tr>
<th>건설사</th>
<td colspan="3" class="info-row">
<input type="hidden" value="" id="const-user-id-` + tableId + `" name="const-user-id" />
<input type="text" value="" class="input-box information1 const-company-dept" id="const-company-dept-` + tableId + `" placeholder="건설사명, 이름, 아이디 또는 이메일">
<input type="text" value="" class="input-box information2" id="const-company-admin-` + tableId + `" placeholder="담당자">
<input type="text" value="010-0000-0000" class="input-box information3" id="const-company-tel-` + tableId + `" placeholder="담당자 연락처">
<label class="check-box unselected-constructor-label" for="unselected-constructor-` + tableId + `"><input type="checkbox" id="unselected-constructor-` + tableId + `">
<span class="unselected-constructor-label-text">건설사 미선정</span>
</label>
<div style="display: none;" class="suggestionList"></div>
</td>
</tr>`;
const gnbPartName = document.getElementById('gnb-part-name' ).value;
const gnbUserName = document.getElementById('gnb-user-name' ).value;
const gnbPhone = document.getElementById('gnb-phone' ).value;
var newTable = '<div class="table-scrollable" data-index="' + tableId + '" data-' + tableId + '>' +
' <table class="table-bordered table-data" data-index="' + tableId + '">' +
' <colgroup>' +
' <col style="width: 15%;">' +
' <col style="width: 35%;">' +
' <col style="width: 15%;">' +
' <col style="width: 35%;">' +
' </colgroup>' +
' <tbody>' +
' <tr>' +
' <th>사업명</th>' +
' <td colspan="3">' +
' <input type="text" value="" onfocusout="duplicateCheckProjectNameLocal(this)" class="input-box" id="const-name-' + tableId + '" placeholder="사업명">' +
' </td>' +
' </tr>' +
' <tr>' +
' <th>사업기간</th>' +
' <td>' +
' <input type="date" value="' + getToday() + '" class="date" id="const-start-date-' + tableId + '">' +
' <span>~</span>' +
' <input type="date" value="' + getToday() + '" class="date date-2" id="const-end-date-' + tableId + '">' +
' </td>' +
' <th>사업단계</th>' +
' <td>' +
' <select class="selectbox" id="const-state-code-' + tableId + '">' +
' <option disabled>사업단계선택</option>' +
' <option selected value="1">타당성조사 및 계획검토</option>' +
' <option value="2">기본설계</option>' +
' <option value="3">실시설계</option>' +
' <option value="4">시공중</option>' +
' <option value="5">준공</option>' +
' <option value="6">유지보수</option>' +
' </select>' +
' </td>' +
' </tr>' +
' <tr>' +
' <th>발주기관</th>' +
' <td colspan="3">' +
' <input type="text" value="' + gnbPartName + '"class="input-box information1" id="master-company-dept-' + tableId + '" placeholder="담당부서">' +
' <input type="text" value="' + gnbUserName + '" class="input-box information2" id="master-company-admin-' + tableId + '" placeholder="담당자">' +
' <input type="text" value="' + gnbPhone + '" class="input-box information3" id="master-company-tel-' + tableId + '" placeholder="담당자 연락처">' +
' </td>' +
' </tr>' +
' <tr>' +
' <th>건설사</th>' +
' <td colspan="3" class="info-row">' +
' <input type="hidden" value="" id="const-user-id-' + tableId + '" name="const-user-id" />' +
' <input type="text" value="" class="input-box information1 const-company-dept" id="const-company-dept-' + tableId + '" placeholder="건설사 명 입력">' +
' <input type="text" value="" class="input-box information2" id="const-company-admin-' + tableId + '" placeholder="담당자 명 입력">' +
' <input type="text" value="010-0000-0000" class="input-box information3" id="const-company-tel-' + tableId + '" placeholder="담당자 연락처 입력">' +
' <label class="check-box unselected-constructor-label" for="unselected-constructor-' + tableId + '">' +
' <input type="checkbox" id="unselected-constructor-' + tableId + '">' +
' <span class="unselected-constructor-label-text">건설사 미선정</span>' +
' </label>' +
' <div style="display: none;" class="suggestionList"></div>' +
' </td>' +
' </tr>';
if (tableId > 1) {
newTable += `
<tr>
<td colspan="4" class="bottom-buttons"><button class="btn-left btn-delete" onclick="removeRow(` + tableId + `)" style="margin-bottom: 0;float: right;"> 삭제</button></td>
</tr>`;
newTable += '<tr>' +
' <td colspan="4" class="bottom-buttons"><button class="btn-left btn-delete" onclick="removeRow(' + tableId + ')" style="margin-bottom: 0;float: right;"> 삭제</button></td>' +
'</tr>';
}
newTable += `</tbody>
</table>
</div>
`;
newTable += '</tbody></table></div>';
document.getElementById('table-container').insertAdjacentHTML('beforeend', newTable);
}
@ -419,10 +423,12 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
const suggestionItem = document.createElement('div');
let userid = '';
let partName = '';
let userName = '';
let email = '';
if (item.userid) userid = item.userid;
if (item.partName) partName = item.partName;
if (item.email) email = item.email;
if (item.userName) userName = item.userName;
const keyword = companyName;
const regex = new RegExp(keyword, 'gi');
@ -434,6 +440,10 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
regex,
'<b style="background:yellow; color:red">' + keyword + '</b>'
);
const boldUserName = item.userName.replace(
regex,
'<b style="background:yellow; color:red">' + keyword + '</b>'
);
const boldEmail = item.email.replace(
regex,
'<b style="background:yellow; color:red">' + keyword + '</b>'
@ -441,7 +451,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
suggestionItem.innerHTML =
'<span class="organizational-structure">' + boldCompanyName + '</span><br />' +
'<span>' + boldConstUserid + '(' + partName + ')' + '/' + boldEmail
'<span>' + boldConstUserid + '(' + boldUserName + ')' + '/' + boldEmail
'</span>';
suggestionItem.addEventListener('click', function () {
@ -449,6 +459,18 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
hiddenUserIdInput.value = item.userid;
suggestionListDiv.style.display = 'none';
setConstInfo(userid, tableContainerDiv); // 건설사 계정 선택시 이름, 연락처 자동 셋팅
// 툴팁에 표시할 아이디 가져오기
const constUserid = item.userid == null ? '' : item.userid;
let toolTip = '';
if( constUserid !== '' ) {
toolTip += '지정된 기업 사용자 아이디: ' + constUserid + '\n';
}
companyNameInput.setAttribute('title', toolTip);
});
suggestionListDiv.appendChild(suggestionItem);
@ -779,6 +801,22 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
orgConstName = item.constCompanyAdmin ? item.constCompanyAdmin : "";
orgConstTel = item.constCompanyTel ? item.constCompanyTel : "";
orgPrjCd = item.projectCode ? item.projectCode : "";
// 툴팁에 표시할 아이디 가져오기
const constUserid = item.constUserid == null ? '' : item.constUserid;
const projectCode = item.projectCode == null ? '' : item.projectCode;
let toolTip = '';
if( constUserid !== '' ) {
toolTip += '지정된 기업 사용자 아이디: ' + constUserid + '\n';
}
if( projectCode !== '' ) {
toolTip += '프로젝트 코드: ' + projectCode + '\n';
}
document.getElementById('const-company-dept-1').setAttribute('title', toolTip);
}
} else if (xhr.readyState === 4) {
  // 요청 실패 시 처리

View File

@ -192,10 +192,24 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
const masterCompanyDept = obj.datas[idx].masterCompanyDept == null ? '-' : obj.datas[idx].masterCompanyDept;
const masterCompanyAdmin = obj.datas[idx].masterCompanyAdmin == null ? '-' : obj.datas[idx].masterCompanyAdmin;
const masterCompanyTel = obj.datas[idx].masterCompanyTel == null ? '-' : obj.datas[idx].masterCompanyTel;
const coinstCompanyDept = obj.datas[idx].coinstCompanyDept == null ? '-' : obj.datas[idx].coinstCompanyDept;
const constCompanyDept = obj.datas[idx].constCompanyDept == null ? '-' : obj.datas[idx].constCompanyDept;
const constCompanyAdmin = obj.datas[idx].constCompanyAdmin == null ? '-' : obj.datas[idx].constCompanyAdmin;
const constCompanyTel = obj.datas[idx].constCompanyTel == null ? '-' : obj.datas[idx].constCompanyTel;
// 툴팁에 표시할 아이디 가져오기
const constUserid = obj.datas[idx].constUserid == null ? '' : obj.datas[idx].constUserid;
const projectCode = obj.datas[idx].projectCode == null ? '' : obj.datas[idx].projectCode;
let toolTip = '';
if( constUserid !== '' ) {
toolTip += '기업 사용자 아이디: ' + constUserid + '\n';
}
if( constCompanyDept !== '' ) {
toolTip += '건설사명: ' + constCompanyDept + '\n';
}
if( projectCode !== '' ) {
toolTip += '프로젝트 코드: ' + projectCode + '\n';
}
// content += '<tr onclick="location.href=\'modify.do?CID=' + obj.datas[idx].cid + '\';" data-cid="' + obj.datas[idx].cid + '">';
content += '<tr onmousedown="handleMouseDown()" onmousemove="handleMouseMove()" onmouseup="handleRowClick(' + obj.datas[idx].cid + ')" data-cid="' + obj.datas[idx].cid + '">';
content += '<td>' + (obj.count - idx - (nCount * (nPage - 1))) + '</td>';
@ -206,7 +220,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
content += '<td>' + masterCompanyDept + '</td>';
content += '<td>' + masterCompanyAdmin + '</td>';
content += '<td>' + masterCompanyTel + '</td>';
content += '<td>' + coinstCompanyDept + '</td>';
content += '<td title="' + toolTip + '">' + constCompanyDept + '</td>';
content += '<td>' + constCompanyAdmin + '</td>';
content += '<td>' + constCompanyTel + '</td>';
content += '</tr>';

View File

@ -91,7 +91,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
const masterCompanyDept = obj.datas[idx].masterCompanyDept == null ? '-' : obj.datas[idx].masterCompanyDept;
const masterCompanyAdmin = obj.datas[idx].masterCompanyAdmin == null ? '-' : obj.datas[idx].masterCompanyAdmin;
const masterCompanyTel = obj.datas[idx].masterCompanyTel == null ? '-' : obj.datas[idx].masterCompanyTel;
const coinstCompanyDept = obj.datas[idx].coinstCompanyDept == null ? '-' : obj.datas[idx].coinstCompanyDept;
const constCompanyDept = obj.datas[idx].constCompanyDept == null ? '-' : obj.datas[idx].constCompanyDept;
const constCompanyAdmin = obj.datas[idx].constCompanyAdmin == null ? '-' : obj.datas[idx].constCompanyAdmin;
const constCompanyTel = obj.datas[idx].constCompanyTel == null ? '-' : obj.datas[idx].constCompanyTel;
content +=
@ -105,7 +105,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
<td>` + masterCompanyDept + `</td>
<td>` + masterCompanyAdmin + `</td>
<td>` + masterCompanyTel + `</td>
<td>` + coinstCompanyDept + `</td>
<td>` + constCompanyDept + `</td>
<td>` + constCompanyAdmin + `</td>
<td>` + constCompanyTel + `</td>
</tr>

View File

@ -103,7 +103,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
const masterCompanyDept = obj.datas[idx].masterCompanyDept == null ? '-' : obj.datas[idx].masterCompanyDept;
const masterCompanyAdmin = obj.datas[idx].masterCompanyAdmin == null ? '-' : obj.datas[idx].masterCompanyAdmin;
const masterCompanyTel = obj.datas[idx].masterCompanyTel == null ? '-' : obj.datas[idx].masterCompanyTel;
const coinstCompanyDept = obj.datas[idx].coinstCompanyDept == null ? '-' : obj.datas[idx].coinstCompanyDept;
const constCompanyDept = obj.datas[idx].constCompanyDept == null ? '-' : obj.datas[idx].constCompanyDept;
const constCompanyAdmin = obj.datas[idx].constCompanyAdmin == null ? '-' : obj.datas[idx].constCompanyAdmin;
const constCompanyTel = obj.datas[idx].constCompanyTel == null ? '-' : obj.datas[idx].constCompanyTel;
content +=
@ -117,7 +117,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
<td>` + masterCompanyDept + `</td>
<td>` + masterCompanyAdmin + `</td>
<td>` + masterCompanyTel + `</td>
<td>` + coinstCompanyDept + `</td>
<td>` + constCompanyDept + `</td>
<td>` + constCompanyAdmin + `</td>
<td>` + constCompanyTel + `</td>
</tr>

View File

@ -105,7 +105,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
const masterCompanyDept = obj.datas[idx].masterCompanyDept == null ? '-' : obj.datas[idx].masterCompanyDept;
const masterCompanyAdmin = obj.datas[idx].masterCompanyAdmin == null ? '-' : obj.datas[idx].masterCompanyAdmin;
const masterCompanyTel = obj.datas[idx].masterCompanyTel == null ? '-' : obj.datas[idx].masterCompanyTel;
const coinstCompanyDept = obj.datas[idx].coinstCompanyDept == null ? '-' : obj.datas[idx].coinstCompanyDept;
const constCompanyDept = obj.datas[idx].constCompanyDept == null ? '-' : obj.datas[idx].constCompanyDept;
const constCompanyAdmin = obj.datas[idx].constCompanyAdmin == null ? '-' : obj.datas[idx].constCompanyAdmin;
const constCompanyTel = obj.datas[idx].constCompanyTel == null ? '-' : obj.datas[idx].constCompanyTel;
content +=
@ -119,7 +119,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
<td>` + masterCompanyDept + `</td>
<td>` + masterCompanyAdmin + `</td>
<td>` + masterCompanyTel + `</td>
<td>` + coinstCompanyDept + `</td>
<td>` + constCompanyDept + `</td>
<td>` + constCompanyAdmin + `</td>
<td>` + constCompanyTel + `</td>
</tr>

View File

@ -105,7 +105,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
const masterCompanyDept = obj.datas[idx].masterCompanyDept == null ? '-' : obj.datas[idx].masterCompanyDept;
const masterCompanyAdmin = obj.datas[idx].masterCompanyAdmin == null ? '-' : obj.datas[idx].masterCompanyAdmin;
const masterCompanyTel = obj.datas[idx].masterCompanyTel == null ? '-' : obj.datas[idx].masterCompanyTel;
const coinstCompanyDept = obj.datas[idx].coinstCompanyDept == null ? '-' : obj.datas[idx].coinstCompanyDept;
const constCompanyDept = obj.datas[idx].constCompanyDept == null ? '-' : obj.datas[idx].constCompanyDept;
const constCompanyAdmin = obj.datas[idx].constCompanyAdmin == null ? '-' : obj.datas[idx].constCompanyAdmin;
const constCompanyTel = obj.datas[idx].constCompanyTel == null ? '-' : obj.datas[idx].constCompanyTel;
content +=
@ -119,7 +119,7 @@ if (request.getSession().getAttribute("CLS") == null || "2".equals(request.getSe
<td>` + masterCompanyDept + `</td>
<td>` + masterCompanyAdmin + `</td>
<td>` + masterCompanyTel + `</td>
<td>` + coinstCompanyDept + `</td>
<td>` + constCompanyDept + `</td>
<td>` + constCompanyAdmin + `</td>
<td>` + constCompanyTel + `</td>
</tr>