아파트 평면도 상세 페이지 추가

This commit is contained in:
yangsh
2025-12-29 13:50:46 +09:00
parent ab39be9602
commit e0672d325c
7 changed files with 1432 additions and 36 deletions

View File

@@ -106,6 +106,11 @@ $routes->group('article', ['namespace' => 'App\Controllers\Article'], function (
$routes->post('apt/ground/uploadFile', 'Ground::uploadFile');
$routes->get('apt/ground/print', 'Ground::print');
$routes->post('apt/ground/saveMemo', 'Ground::saveMemo');
$routes->post('apt/ground/saveKeeper', 'Ground::saveKeeper');
$routes->post('apt/ground/statusChange', 'Ground::statusChange');
$routes->post('apt/ground/saveNote', 'Ground::saveNote');
});

View File

@@ -217,15 +217,156 @@ class Ground extends BaseController
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
}
$bonbu = $this->model->getBonbuList();
$team = $this->model->getTeamList();
$user = $this->model->getUserList();
// 상세정보
$apt = $this->model->getDetail($rcpt_no, $hscp_no);
// 동일단지
$rdata = $this->model->getDetailLists($rcpt_no, $hscp_no);
// 변경이력
$history = $this->model->getHistory($rcpt_no);
return view("pages/article/detail2", [
'bonbu' => $bonbu,
'team' => $team,
'user' => $user,
'apt' => $apt,
'rdata' => $rdata,
'history' => $history,
]);
}
// 메모저장
public function saveMemo()
{
try {
$data = [
'rcpt_no' => $this->request->getPost('rcpt_no'),
'memo' => $this->request->getPost('memo'),
];
// UPDATE apt_ground
$this->model->saveMemo($data);
return $this->response->setJSON([
'code' => '0',
'msg' => 'success'
]);
} catch (\Exception $e) {
return $this->response->setJSON([
'code' => '9',
'msg' => $e->getMessage(),
]);
}
}
// 담당자 변경
public function saveKeeper()
{
try {
$data = [
'rcpt_no' => $this->request->getPost('rcpt_no'),
'bonbu' => $this->request->getPost('bonbu'),
'team' => $this->request->getPost('team'),
'user' => $this->request->getPost('user'),
];
// UPDATE apt_ground
$this->model->saveKeeper($data);
return $this->response->setJSON([
'code' => '0',
'msg' => 'success'
]);
} catch (\Exception $e) {
return $this->response->setJSON([
'code' => '9',
'msg' => $e->getMessage(),
]);
}
}
// 단지상태변경
public function statusChange()
{
$lib = new MyUpload();
try {
$type = $this->request->getPost('type');
$rcpt_no = $this->request->getPost('rcpt_no');
if ($type === "phoX") {
$apt = $this->model->getDetail($rcpt_no, "");
if (!empty($apt['pho_no'])) {
$path = $apt['file_path'] . "" . $apt['filenm_up'];
$lib->deleteFile($path);
}
}
// UPDATE apt_ground
$this->model->statusChange($rcpt_no, $type);
return $this->response->setJSON([
'code' => '0',
'msg' => 'success'
]);
} catch (\Exception $e) {
return $this->response->setJSON([
'code' => '9',
'msg' => $e->getMessage(),
]);
}
}
// 단지 특이사항 저장
public function saveNote()
{
try {
$rcpt_no = $this->request->getPost('rcpt_no');
$data = [
'rcpt_no' => $rcpt_no,
'note' => $this->request->getPost('note'),
];
// UPDATE apt_ground
$this->model->saveNote($data);
return $this->response->setJSON([
'code' => '0',
'msg' => 'success'
]);
} catch (\Exception $e) {
return $this->response->setJSON([
'code' => '9',
'msg' => $e->getMessage(),
]);
}
}
// 파일업로드(평면도)

View File

@@ -110,6 +110,26 @@ class MyUpload
return $this->s3_data;
}
/**
*
*/
public function deleteFile($key)
{
$s3Client = $this->makeS3Client();
try {
$s3Client->deleteObject([
'Bucket' => NCLOUD_S3_BUCKET,
'Key' => ltrim($key, '/'),
]);
return true;
} catch (\Throwable $e) {
return false;
}
}
/**
* S3(NCLOUD) 파일 업로드
* 추가일 2025.12.24

View File

@@ -637,7 +637,7 @@ class GroundModel extends Model
,a.charger, a.dept_sq ,(SELECT pdept_sq FROM departments WHERE dept_sq = a.dept_sq) bonbu
,a.send_end_tm, a.supply_no_tm
,d.pho_cate2, d.pho_explain, d.pho_up_nu
,gp.filenm_up, gp.file_path, gp.insert_tm
,gp.pho_no ,gp.filenm_up, gp.file_path, gp.thumb_nm, gp.cloud_upload_yn, gp.insert_tm
FROM
apt_ground a
LEFT JOIN apt_category d ON a.rcpt_no = d.rcpt_no
@@ -645,19 +645,246 @@ class GroundModel extends Model
FROM apt_ground_photo p
WHERE p.rcpt_no = a.rcpt_no
ORDER BY p.pho_no DESC
LIMIT 1)
LIMIT 1) AND gp.use_yn = 'Y'
WHERE a.rcpt_no = {$rcpt_no} ";
if (!empty($hscp_no)) {
$sql .= "AND a.hscp_no = {$hscp_no} ";
}
WHERE a.rcpt_no = {$rcpt_no} AND a.hscp_no = {$hscp_no} ";
$query = $this->db->query($sql, [$rcpt_no]);
return $query->getRowArray();
}
// 동일단지
public function getDetailLists($rcpt_no, $hscp_no)
{
$sql = "SELECT
a.rcpt_no, a.hscp_no, a.part_no, a.addr, a.addr2, a.rcpt_hscp_nm, a.move_ym, a.households_cnt, a.dong_cnt, a.pyeong_cnt, a.apt_cate_nm, a.region_cd, a.rcpt_x, a.rcpt_y
,a.vdo_up_tm, DATE_FORMAT(a.vdo_up_tm, '%Y-%m-%d') as rdate_dt_vdo ,DATE_FORMAT(a.vdo_up_tm, '%H:%i:%s') as rdate_tm_vdo
,a.check_tm, DATE_FORMAT(a.check_tm, '%Y-%m-%d') as rdate_dt_chk ,DATE_FORMAT(a.check_tm, '%H:%i:%s') as rdate_tm_chk
,a.memo, a.note, a.video_target, a.vdo_up_ynx, a.not_vdo_reson, a.apt_step, a.check_yn, a.resend_yn, a.write_complete_yn, a.all_no_pho
,a.write_complete_tm, DATE_FORMAT(a.write_complete_tm, '%Y-%m-%d') as rdate_dt_cmpl ,DATE_FORMAT(a.write_complete_tm, '%H:%i:%s') as rdate_tm_cmpl
,a.charger, a.dept_sq ,(SELECT pdept_sq FROM departments WHERE dept_sq = a.dept_sq) bonbu, b.usr_nm, i.dept_nm
,a.send_end_tm, a.supply_no_tm
,d.pho_cate2, d.pho_explain, d.pho_up_nu
,gp.pho_no, gp.filenm ,gp.filenm_up, gp.file_path, gp.thumb_nm, gp.cloud_upload_yn, gp.insert_tm
FROM
apt_ground a
LEFT JOIN apt_category d ON a.rcpt_no = d.rcpt_no
LEFT JOIN apt_ground_photo gp ON gp.pho_no = (SELECT p.pho_no
FROM apt_ground_photo p
WHERE p.rcpt_no = a.rcpt_no
ORDER BY p.pho_no DESC
LIMIT 1) AND gp.use_yn = 'Y'
LEFT JOIN users b ON a.charger = b.usr_id
LEFT JOIN departments i ON a.dept_sq = i.dept_sq
WHERE a.rcpt_no = {$rcpt_no} AND a.hscp_no != {$hscp_no} ";
$query = $this->db->query($sql);
return $query->getResultArray();
}
// 정보변경이력
public function getHistory($rcpt_no)
{
$sql = " SELECT seq," .
" rcpt_no, " .
" apt_step, get_code_name('APT_GROUND_STEP',apt_step) AS apt_step_nm, " .
" changed_type, get_code_name('APT_GROUND_CHANGED_TYPE',changed_type) AS changed_type_nm, " .
" changed_detail, get_code_name('APT_GROUND_CHANGED_DETAIL',changed_detail) AS changed_detail_nm, " .
" charged_id, " .
" changed_tm, DATE_FORMAT(changed_tm, '%Y-%m-%d') as rdate_dt, DATE_FORMAT(changed_tm, '%H:%i:%s') as rdate_tm" .
" FROM apt_ground_history" .
" WHERE rcpt_no = ?" .
" ORDER BY changed_tm DESC";
$query = $this->db->query($sql, [$rcpt_no]);
return $query->getResultArray();
}
// 메모저장
public function saveMemo($data)
{
$sql = "UPDATE apt_ground SET
memo = '{$data['memo']}'
WHERE rcpt_no = {$data['rcpt_no']}
";
if ($this->db->query($sql) === false) {
return [
'success' => false,
'msg' => '저장실패',
];
}
$row = $this->getDetail($data['rcpt_no'], "");
$this->saveHistory($data['rcpt_no'], $row['apt_step'], 'C', 'A1', session('usr_id'));
return [
'success' => true,
];
}
// 담당자 변경
public function saveKeeper($data)
{
$sql = "UPDATE apt_ground SET
dept_sq = {$data['team']}, charger = '{$data['user']}'
WHERE rcpt_no = {$data['rcpt_no']}
";
if ($this->db->query($sql) === false) {
return [
'success' => false,
'msg' => '저장실패',
];
}
$row = $this->getDetail($data['rcpt_no'], "");
$this->saveHistory($data['rcpt_no'], $row['apt_step'], 'C', 'A1', session('usr_id'));
return [
'success' => true,
];
}
// 단지상태변경
public function statusChange($rcpt_no, $type)
{
$this->db->transStart();
$data = [
$rcpt_no
];
if ($type === "phoX") {
$detail = 'C1';
$sql = "UPDATE apt_ground" .
" SET gpho_up_yn = 'N'" .
" ,apt_step = 'S01'" .
" WHERE rcpt_no = ?";
if ($this->db->query($sql, $data) === false) {
return [
'success' => false,
'msg' => '저장실패',
];
}
$sql = "delete from apt_ground_photo" .
" WHERE rcpt_no = ?";
$this->db->query($sql, $data);
} else if ($type === "phoY") {
$detail = 'C3';
$sql = "UPDATE apt_ground" .
" SET gpho_up_yn = 'Y'" .
" ,apt_step = 'S03'" .
" WHERE rcpt_no = ?";
if ($this->db->query($sql, $data) === false) {
return [
'success' => false,
'msg' => '저장실패',
];
}
$sql = "UPDATE apt_ground_photo" .
" SET insert_tm = NOW()" .
" WHERE rcpt_no = ?";
$this->db->query($sql, $data);
} else if ($type === "sendE") {
$detail = 'C4';
$sql = "UPDATE apt_ground" .
" SET send_end_tm = NOW()" .
" ,supply_no_tm = NULL" .
" ,apt_step = 'S04'" .
" WHERE rcpt_no = ?";
if ($this->db->query($sql, $data) === false) {
return [
'success' => false,
'msg' => '저장실패',
];
}
} else if ($type === "suppN") {
$detail = 'C2';
$sql = "UPDATE apt_ground" .
" SET all_no_pho = 'Y'" .
" ,apt_step = 'S02'" .
" ,supply_no_tm = NOW()" .
" ,send_end_tm = NULL" .
" WHERE rcpt_no = ?";
if ($this->db->query($sql, $data) === false) {
return [
'success' => false,
'msg' => '저장실패',
];
}
}
$row = $this->getDetail($rcpt_no, "");
$this->saveHistory($rcpt_no, $row['apt_step'], 'E', $detail, session('usr_id'));
$this->db->transComplete();
return [
'success' => true,
];
}
// 단지 특이사항 저장
public function saveNote($data)
{
$sql = "UPDATE apt_ground SET
note = '{$data['note']}'
WHERE rcpt_no = {$data['rcpt_no']}
";
if ($this->db->query($sql) === false) {
return [
'success' => false,
'msg' => '저장실패',
];
}
$row = $this->getDetail($data['rcpt_no'], "");
$this->saveHistory($data['rcpt_no'], $row['apt_step'], 'C', 'D1', session('usr_id'));
return [
'success' => true,
];
}
// 평면도 정보 저장
public function saveImg($data)
{
$this->db->transStart();
$sql = "INSERT INTO apt_ground_photo
(rcpt_no, filenm, filenm_up, file_ext, insert_tm, file_path, thumb_path, thumb_nm, use_yn, cloud_upload_yn)
VALUES
@@ -673,9 +900,38 @@ class GroundModel extends Model
];
}
$sql = "UPDATE apt_ground SET
gpho_up_yn = 'Y', apt_step = 'S03'
WHERE rcpt_no = {$data['rcpt_no']}
";
$this->db->query($sql);
$this->db->transComplete();
return [
'success' => true,
];
}
// 이력 저장
public function saveHistory($rcpt_no, $apt_step, $changed_type, $changed_detail, $charged_id)
{
$sql = "INSERT INTO apt_ground_history" .
" (rcpt_no, apt_step, changed_type, changed_detail, charged_id, changed_tm)" .
" VALUES (?, ?, ?, ?, ?, NOW())";
$data = [
$rcpt_no,
$apt_step,
$changed_type,
$changed_detail,
$charged_id
];
$res = $this->db->query($sql, $data);
}
}

View File

@@ -93,6 +93,21 @@
<?php
// 이 부모(menu)의 자식 중 현재 path와 일치하는 메뉴가 있는지 체크
$hasActiveChild = false;
$path = parse_url($path, PHP_URL_PATH);
// 2. 숫자 파라미터 제거 (/detail/123 → /detail)
$path = preg_replace('#/\d+#', '', $path);
// 3. 끝 슬래시 정리
$path = rtrim($path, '/');
switch ($path) {
case "/article/apt/detail":
$path = "/article/apt/lists";
break;
case "/article/apt/ground/detail":
$path = "/article/apt/lists2";
break;
}
foreach ($sMenu as $subMenu) {
if ($menu["mnu_id"] == $subMenu["mnu_pid"] && $path === $subMenu["mnu_url"]) {
$hasActiveChild = true;

File diff suppressed because it is too large Load Diff

View File

@@ -647,9 +647,9 @@
// { 'className': 'text-center', 'targets': [0, 2, 3, 4] },
],
columns: [
{ data: null, render: fn_chk_render, width: "50px" },
{ data: null, render: fn_chk_render, width: "50px", className: "dt-no-rowclick" },
{ data: 'apt_step', render: fn_stat_render, width: "80px" },
{ data: 'apt_step', render: fn_stat_render, width: "80px", },
{ data: 'part_no', width: "80px" },
{ data: 'hscp_no', width: "100px" },
{ data: 'addr' },
@@ -657,9 +657,9 @@
{ data: 'pyeong_cnt', width: "80px" },
{ data: 'dept_nm', width: "80px" },
{ data: 'usr_nm', width: "50px" },
{ data: null, render: fn_btn_upload },
{ data: null, render: fn_btn_preview, width: "80px" },
{ data: null, render: fn_btn_download, width: "80px" },
{ data: null, render: fn_btn_upload, className: "dt-no-rowclick" },
{ data: null, render: fn_btn_preview, width: "80px", className: "dt-no-rowclick" },
{ data: null, render: fn_btn_download, width: "80px", className: "dt-no-rowclick" },
],
// 옵션들 예시
@@ -669,10 +669,14 @@
serverSide: true,
});
$('#resultList tbody').on('click', 'tr', function () {
$('#resultList tbody').on('click', 'tr', function (e) {
if ($(e.target).closest('td.dt-no-rowclick').length) return;
const rowData = table.row(this).data();
if (!rowData) return;
const rcpt_no = rowData.rcpt_no;
const hscp_no = rowData.hscp_no;
location.href = "<?= site_url('article/apt/ground/detail') ?>/" + rcpt_no + "/" + hscp_no;
@@ -705,7 +709,8 @@
});
// 리스트 파일업로드
$(document).on("click", ".btn-upload-photo", function () {
$(document).on("click", ".btn-upload-photo", function (e) {
e.stopPropagation();
const row = $('#resultList').DataTable()
.row($(this).closest('tr'))
.data();
@@ -715,6 +720,12 @@
$("#uploadModal").modal("show");
});
// 미리보기
$(document).on('click', '.btn-preview', function (e) {
e.stopPropagation(); // 행 클릭 방지(2중 안전)
fn_preview($(this).data('src'));
});
/**
* 파일 Dropzone
* */
@@ -791,7 +802,7 @@
});
dz.on("queuecomplete", function () {
// table.ajax.reload()
table.ajax.reload()
});
dz.on("successmultiple", function () {
@@ -1038,20 +1049,17 @@
// 미리보기 btn
function fn_btn_preview(data, type, row) {
var str = "";
if (row.pho_no == null) return '';
if (row.pho_no != null) {
var src = "";
if (row.cloud_upload_yn == "Y") {
src = '<?= NCLOUD_OBJECT_STORAGE_URL ?>' + '' + row.file_path + '' + row.filenm_up;
} else {
src = row.file_path + '' + row.filenm_up;
}
let src = (row.cloud_upload_yn == "Y")
? '<?= NCLOUD_OBJECT_STORAGE_URL ?>' + row.file_path + row.filenm_up
: row.file_path + row.filenm_up;
str = `<a onclick="fn_preview('${src}');">미리보기</a>`;
}
return str;
return `
<button type="button" class="btn btn-sm btn-link p-0 btn-preview" data-src="${src}">
미리보기
</button>
`;
}
// 다운로드 btn