실적관리 추가

This commit is contained in:
yangsh
2025-12-18 14:50:48 +09:00
parent 80826843d7
commit 59db781aef
58 changed files with 9587 additions and 28 deletions

View File

@@ -0,0 +1,239 @@
<?php
if (!function_exists('limitHscpMarketPriceInfo')) {
/**
* 해당 매물의 시세를 확인후 상한가의 200% ~ 하한가의 70% 이내의 범위에 값이 설정되어 있는지 확인
* @param string $trade_type 거래종류
* @param string $hscp_no 단지코드
* @param string $ptp_no 평형코드
* @param string $atcl_amt 가격
*/
function limitHscpMarketPriceInfo($CI, $trade_type, $hscp_no, $ptp_no, $atcl_amt)
{
$return = array();
if (!empty($hscp_no) && !empty($ptp_no)) {
$hscpMarketPriceInfo = $CI->call_kiso_api->hscpMarketPriceInfo($hscp_no, $ptp_no);
if (isset($hscpMarketPriceInfo['error'])) { //결과값 확인
if ($hscpMarketPriceInfo['error']['code'] == 'VC027') {
$return = array();
} else {
$return = $hscpMarketPriceInfo['error'];
}
} else {
$limitH = 0;
$limitL = 0;
// 상한가, 하한가 체크 ( 상한가 * 2, 하한가 * 0.7) 이내의 범위에 가격이 있어야 함.
if ($trade_type == 'A1') {
// 매매
if (isset($hscpMarketPriceInfo['result']['deal_uplmt_prc'])) {
$limitH = $hscpMarketPriceInfo['result']['deal_uplmt_prc'];
}
if (isset($hscpMarketPriceInfo['result']['deal_lwlmt_prc'])) {
$limitL = $hscpMarketPriceInfo['result']['deal_lwlmt_prc'];
}
} elseif ($trade_type == 'B1') {
// 전세
if (isset($hscpMarketPriceInfo['result']['lease_uplmt_prc'])) {
$limitH = $hscpMarketPriceInfo['result']['lease_uplmt_prc'];
}
if (isset($hscpMarketPriceInfo['result']['lease_lwlmt_prc'])) {
$limitL = $hscpMarketPriceInfo['result']['lease_lwlmt_prc'];
}
}
if (!empty($limitH)) {
$limitH = $limitH * 2;
if ($limitH < $atcl_amt) {
$return = array('code' => 'ERC_02', 'message' => '최근 시세 하한가 70% ~ 상한가 200% 혹은 네이버 분양 서비스 내 평균 분양가격 하한가 60%(시세가 없는 분양권)를 벗어나는 가격입니다.');
}
}
if (!empty($limitL)) {
$limitL = $limitL * 0.7;
if ($limitL > $atcl_amt) {
$return = array('code' => 'ERC_03', 'message' => '최근 시세 하한가 70% ~ 상한가 200% 혹은 네이버 분양 서비스 내 평균 분양가격 하한가 60%(시세가 없는 분양권)를 벗어나는 가격입니다.');
}
}
}
}
return $return;
}
}
/**
* 공동중개 매물 stat_cd 이름 변경
*/
function getCdChangeNm($stat_cd)
{
switch ($stat_cd) {
case "30":
return "공동중개 확인중";
break;
}
}
/**
* 클라이언트 아이피 체크
*/
function getRealClientIp()
{
$ipaddress = '';
// HTTP_CLIENT_IP 확인 (일부 프록시에서 사용)
if (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
}
// HTTP_X_FORWARDED_FOR 확인 (프록시/로드 밸런서에서 가장 흔하게 사용)
else if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
// HTTP_X_FORWARDED_FOR는 쉼표로 구분된 여러 IP를 포함할 수 있음
// 보통 첫 번째 IP가 실제 클라이언트 IP
if (strpos($ipaddress, ',') !== false) {
$ips = explode(',', $ipaddress);
$ipaddress = trim($ips[0]);
}
}
// 다른 X-Forwarded 헤더들 확인 (덜 흔하지만 확인 필요)
else if (isset($_SERVER['HTTP_X_FORWARDED'])) {
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
} else if (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
} else if (isset($_SERVER['HTTP_FORWARDED'])) {
$ipaddress = $_SERVER['HTTP_FORWARDED'];
}
// X-Real-IP 확인 (Nginx와 같은 리버스 프록시에서 주로 사용)
else if (isset($_SERVER['X-Real-IP'])) {
$ipaddress = $_SERVER['X-Real-IP'];
}
// REMOTE_ADDR 확인 (가장 직접적인 연결에서 신뢰할 수 있음)
else if (isset($_SERVER['REMOTE_ADDR'])) {
$ipaddress = $_SERVER['REMOTE_ADDR'];
} else {
$ipaddress = '알수없음';
}
return $ipaddress;
}
function specailCharChange($str)
{
if (!$str)
return '';
$str = str_replace(">", "", $str);
$str = str_replace("<", "", $str);
return $str;
}
/**
* csv 용
* @param mixed $str
* @return array|string
*/
function csvDataReplace($str)
{
$str = str_replace("\r\n", "", $str);
$str = str_replace(",", " ", $str);
return $str;
}
if (!function_exists('str_contains')) {
function str_contains($haystack, $needle)
{
return '' === $needle || false !== strpos($haystack, $needle);
}
}
/**
* Checks if a file exists at a given URL by attempting to retrieve its HTTP headers.
* This function is specifically designed to work with NCLOUD Object Storage URLs.
* It includes a timeout to prevent indefinite blocking due to unresponsive external resources.
*
* @param string $url The relative URL of the file within NCLOUD Object Storage.
* @return bool True if the file exists (HTTP 2xx status), false otherwise or on error/timeout.
*/
function url_fileExist($url)
{
// 134: 입력 URL이 비어있는지 확인. 비어있으면 즉시 false 반환.
if (empty($url)) {
return false;
}
// 135: NCLOUD_OBJECT_STORAGE_URL 상수를 사용하여 완전한 URL을 구성.
// 이 상수는 NCLOUD Object Storage의 기본 URL (예: 'https://kr.object.ncloudstorage.com/')을 포함해야 합니다.
$fullUrl = NCLOUD_OBJECT_STORAGE_URL . $url;
// 136: (빈 라인)
// 137: get_headers() 호출에 타임아웃을 적용하기 위한 스트림 컨텍스트 생성.
// 'http' 옵션에 'timeout'을 설정하여 PHP가 응답을 기다리는 최대 시간을 지정합니다.
// 'method'를 'HEAD'로 설정하여 파일 내용을 다운로드하지 않고 헤더만 요청하므로 효율적입니다.
// 'ssl' 옵션은 HTTPS 연결 시 SSL/TLS 인증서 검증 오류를 방지합니다.
// 운영 환경에서는 'verify_peer'와 'verify_peer_name'을 'true'로 설정하여 보안을 강화하는 것을 권장하며,
// 적절한 CA 인증서 번들 경로를 'cafile' 또는 'capath'로 지정해야 합니다.
$context = stream_context_create(array(
'http' => array(
'timeout' => 5, // 응답을 5초 동안 기다림 (이 값은 네트워크 환경과 외부 서비스 응답 시간에 따라 조정 가능)
'method' => 'HEAD' // HEAD 요청은 파일 존재 여부 확인에 충분하며 대역폭을 절약합니다.
),
'ssl' => array(
'verify_peer' => false, // 경고: 프로덕션 환경에서는 'true'로 설정하고 CA 인증서를 구성하여 보안을 강화해야 합니다.
'verify_peer_name' => false, // 경고: 프로덕션 환경에서는 'true'로 설정하고 CA 인증서를 구성하여 보안을 강화해야 합니다.
)
));
// get_headers() 함수를 호출하여 HTTP 헤더를 가져옵니다.
// @ suppression operator를 사용하여 네트워크 오류 등으로 인한 PHP 경고를 억제합니다.
// $context를 세 번째 인자로 전달하여 위에서 정의한 타임아웃 및 기타 옵션을 적용합니다.
$array = @get_headers($fullUrl, 0, $context);
// 헤더를 가져오지 못했거나 (예: 타임아웃, 네트워크 오류) false가 반환된 경우 처리.
// 이 경우 파일이 존재하지 않거나 접근할 수 없는 것으로 간주합니다.
if ($array === false) {
// 이 곳에 오류 로깅 또는 추가적인 오류 처리 로직을 추가할 수 있습니다.
// 예: error_log("Failed to get headers for URL: " . $fullUrl . " at " . __FILE__ . ":" . __LINE__);
return false;
}
// HTTP 응답의 첫 번째 줄(상태 코드)에서 숫자로 된 상태 코드를 추출합니다.
// 정규식을 사용하여 "HTTP/1.1 200 OK"와 같은 문자열에서 "200" 부분을 추출합니다.
if (preg_match('/^HTTP\/\d\.\d\s(\d{3})/', $array[0], $matches)) {
$statusCode = (int) $matches[1];
// HTTP 상태 코드가 2xx (성공) 범위인지 확인합니다.
// 200 OK, 201 Created, 202 Accepted 등 성공적인 응답을 모두 포함합니다.
return ($statusCode >= 200 && $statusCode < 300);
}
// 만약 위 preg_match가 실패하거나, 응답 형식이 예상과 다르면,
// 원래 로직대로 "200 OK" 문자열 포함 여부로 한 번 더 확인합니다.
// 이는 후방 호환성을 위한 것이며, 위의 상태 코드 확인 로직이 더 견고합니다.
return str_contains($array[0], "200 OK");
}
function realFilePath($url)
{
if (empty($url))
return;
if (url_fileExist($url)) {
$return_url = NCLOUD_OBJECT_STORAGE_URL . $url;
} else {
$return_url = $url;
}
return $return_url;
}
function han($s)
{
return reset(json_decode('{"s":"' . $s . '"}'));
}
// function to_han ($str) { return preg_replace('/(\\\u[a-f0-9]+)+/e','han("$0")',$str); }