아파트평면도 엑셀업로드 추가
Some checks failed
Close Pull Request / main (pull_request_target) Has been cancelled
Some checks failed
Close Pull Request / main (pull_request_target) Has been cancelled
This commit is contained in:
@@ -103,6 +103,7 @@ $routes->group('article', ['namespace' => 'App\Controllers\Article'], function (
|
|||||||
*/
|
*/
|
||||||
$routes->get('apt/ground/getAptLists', 'Ground::getAptLists');
|
$routes->get('apt/ground/getAptLists', 'Ground::getAptLists');
|
||||||
$routes->get('apt/ground/excel', 'Ground::excel');
|
$routes->get('apt/ground/excel', 'Ground::excel');
|
||||||
|
$routes->post('apt/ground/uploadExcel', 'Ground::uploadExcel');
|
||||||
$routes->post('apt/ground/chgAptDamdang', 'Ground::chgAptDamdang');
|
$routes->post('apt/ground/chgAptDamdang', 'Ground::chgAptDamdang');
|
||||||
$routes->post('apt/ground/uploadFile', 'Ground::uploadFile');
|
$routes->post('apt/ground/uploadFile', 'Ground::uploadFile');
|
||||||
$routes->get('apt/ground/print', 'Ground::print');
|
$routes->get('apt/ground/print', 'Ground::print');
|
||||||
|
|||||||
@@ -84,6 +84,57 @@ class Ground extends BaseController
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 엑셀 업로드
|
||||||
|
public function uploadExcel()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
$payload = $this->request->getJSON(true);
|
||||||
|
$datas = $payload['datas'] ?? null;
|
||||||
|
|
||||||
|
if (count($datas) === 0) {
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'code' => '9',
|
||||||
|
'msg' => "데이터 없음",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($datas as $data) {
|
||||||
|
$rdate = date("Y-m-d H:i:s");
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'hscp_no' => $data[1],
|
||||||
|
'region_cd' => $data[2],
|
||||||
|
'part_no' => $data[0],
|
||||||
|
'apt_step' => 'S01',
|
||||||
|
'addr' => $data[3] . ' ' . $data[4] . ' ' . $data[5],
|
||||||
|
'addr2' => $data[6],
|
||||||
|
'rcpt_hscp_nm' => $data[7],
|
||||||
|
'apt_cate_nm' => $data[8],
|
||||||
|
'pyeong_cnt' => $data[9],
|
||||||
|
'rcpt_x' => $data[10],
|
||||||
|
'rcpt_y' => $data[11],
|
||||||
|
'ginsert_tm' => $rdate,
|
||||||
|
];
|
||||||
|
|
||||||
|
// INSERT apt_ground
|
||||||
|
$this->model->saveExcelUploadData($params);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'code' => '0',
|
||||||
|
'msg' => 'success'
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'code' => '9',
|
||||||
|
'msg' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 엑셀 다운로드
|
// 엑셀 다운로드
|
||||||
public function excel()
|
public function excel()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -468,6 +468,33 @@ class GroundModel extends Model
|
|||||||
return $query->getResultArray();
|
return $query->getResultArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 엑셀 업로드 저장
|
||||||
|
public function saveExcelUploadData($params)
|
||||||
|
{
|
||||||
|
$this->db->transStart();
|
||||||
|
|
||||||
|
$builder = $this->db->table('apt_ground');
|
||||||
|
$res = $builder->insert($params);
|
||||||
|
|
||||||
|
if ($res === false) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'msg' => "구분코드 : {$params['part_no']} 저장실패",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$rcpt_no = $this->db->insertID();
|
||||||
|
|
||||||
|
$this->saveHistory($rcpt_no, $params['apt_step'], 'U', 'U1', session('usr_id'));
|
||||||
|
|
||||||
|
$this->db->transComplete();
|
||||||
|
|
||||||
|
// 성공
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// 엑셀 다운로드
|
// 엑셀 다운로드
|
||||||
public function getExcelList($data)
|
public function getExcelList($data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,6 +44,15 @@
|
|||||||
background-color: #ff0000 !important;
|
background-color: #ff0000 !important;
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#excelList.dataTable {
|
||||||
|
width: max-content !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.dataTable td,
|
||||||
|
table.dataTable th {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<h1>아파트 평면도 내역</h1>
|
<h1>아파트 평면도 내역</h1>
|
||||||
@@ -279,6 +288,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ml-auto">
|
<div class="ml-auto">
|
||||||
|
<button class="btn btn-sm btn-outline-secondary" id="excel-upload">
|
||||||
|
<i class="fa fa-fw" aria-hidden="true" title="file-excel-o"></i> 엑셀업로드
|
||||||
|
</button>
|
||||||
|
|
||||||
<button class="btn btn-sm btn-outline-success" id="excel-download">
|
<button class="btn btn-sm btn-outline-success" id="excel-download">
|
||||||
<i class="fa fa-fw" aria-hidden="true" title="file-excel-o"></i> 엑셀다운로드
|
<i class="fa fa-fw" aria-hidden="true" title="file-excel-o"></i> 엑셀다운로드
|
||||||
</button>
|
</button>
|
||||||
@@ -386,6 +399,69 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="excelModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-xl">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">엑셀 업로드</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<!-- 업로드 영역 -->
|
||||||
|
<div class="d-flex align-items-center gap-3 mb-3">
|
||||||
|
<input type="file" id="excel" class="form-control" accept=".xlsx,.xls,.csv"
|
||||||
|
style="max-width: 320px;">
|
||||||
|
|
||||||
|
<a href="/plugin/sample/sample_apt.xlsx" download="아파트단지_샘플양식"
|
||||||
|
class="btn btn-outline-secondary btn-sm">
|
||||||
|
샘플양식 다운로드
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 안내 문구 -->
|
||||||
|
<div class="alert alert-light py-2 mb-3">
|
||||||
|
<ul class="mb-0 small">
|
||||||
|
<li>엑셀 첫 행은 헤더로 인식됩니다.</li>
|
||||||
|
<li>컬럼 순서 및 개수는 샘플양식과 동일해야 합니다.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 테이블 영역 -->
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table id="excelList"
|
||||||
|
class="table table-sm table-hover table-striped table-bordered align-middle text-center mb-0">
|
||||||
|
<thead class="table-light">
|
||||||
|
<tr>
|
||||||
|
<th>구분코드</th>
|
||||||
|
<th>단지코드</th>
|
||||||
|
<th>법정동코드</th>
|
||||||
|
<th>시/도</th>
|
||||||
|
<th>시/군/구</th>
|
||||||
|
<th>읍/면/동</th>
|
||||||
|
<th>상세주소</th>
|
||||||
|
<th>단지명</th>
|
||||||
|
<th>구분명</th>
|
||||||
|
<th>평수</th>
|
||||||
|
<th>총동수</th>
|
||||||
|
<th>경도</th>
|
||||||
|
<th>위도</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="btnExcelUpload">저장</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<?= $this->endSection() ?>
|
<?= $this->endSection() ?>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" />
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" />
|
||||||
@@ -685,6 +761,137 @@
|
|||||||
table.ajax.reload()
|
table.ajax.reload()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 엑셀업로드 click
|
||||||
|
$("#excel-upload").on("click", function () {
|
||||||
|
$("#excel").val("");
|
||||||
|
$("#excelList").DataTable().clear().destroy();
|
||||||
|
|
||||||
|
$("#excelModal").modal("show");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 엑셀 업로드
|
||||||
|
$("#excel").on("change", async function () {
|
||||||
|
const file = this.files[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
const bodyRows = await readExcelBodyOnly(file);
|
||||||
|
renderExcelDataTable(bodyRows);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 엑셀 업로드 저장
|
||||||
|
$("#btnExcelUpload").on("click", function () {
|
||||||
|
|
||||||
|
const dt = $("#excelList").DataTable();
|
||||||
|
|
||||||
|
// 전체 row 데이터 (모든 페이지)
|
||||||
|
const excelData = dt.rows().data().toArray();
|
||||||
|
|
||||||
|
if (excelData.length === 0) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "업로드할 데이터가 없습니다.",
|
||||||
|
icon: "warning"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = [
|
||||||
|
"구분코드", "단지코드", "법정동코드"
|
||||||
|
, "시/도", "시/군/구", "읍/면/동", "상세주소"
|
||||||
|
, "단지명", "구분명", "평수", "총동수", "경도", "위도"
|
||||||
|
];
|
||||||
|
|
||||||
|
const errors = [];
|
||||||
|
let hasError = false;
|
||||||
|
for (let rowIdx = 0; rowIdx < excelData.length; rowIdx++) {
|
||||||
|
const row = excelData[rowIdx];
|
||||||
|
|
||||||
|
for (let colIdx = 0; colIdx < headers.length; colIdx++) {
|
||||||
|
const colName = headers[colIdx];
|
||||||
|
const val = row[colIdx];
|
||||||
|
|
||||||
|
|
||||||
|
if (val === undefined || val === null || String(val).trim() === "") {
|
||||||
|
Swal.fire({
|
||||||
|
title: `${rowIdx + 1}행 ${colName} 데이터 누락`,
|
||||||
|
icon: "warning"
|
||||||
|
});
|
||||||
|
|
||||||
|
hasError = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasError) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasError) return;
|
||||||
|
|
||||||
|
swal.fire({
|
||||||
|
text: "저장 하시겠습니까?",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "예",
|
||||||
|
cancelButtonText: "아니오",
|
||||||
|
closeOnConfirm: false,
|
||||||
|
closeOnCancel: true,
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
cancelButtonColor: "#d33",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/article/apt/ground/uploadExcel',
|
||||||
|
contentType: 'application/json;charset=UTF-8',
|
||||||
|
method: 'POST',
|
||||||
|
data: JSON.stringify({ datas: excelData }),
|
||||||
|
beforeSend: function () {
|
||||||
|
blockUI.blockPage({
|
||||||
|
message: tpl
|
||||||
|
})
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
blockUI.unblockPage()
|
||||||
|
},
|
||||||
|
error: function (xhr, error, thrown) {
|
||||||
|
blockUI.unblockPage()
|
||||||
|
var msg = "";
|
||||||
|
if (xhr.responseText != null) {
|
||||||
|
msg = xhr.responseText
|
||||||
|
} else {
|
||||||
|
msg = "잠시후 다시 시도해 주세요."
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: msg,
|
||||||
|
icon: "error"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
success: function (result) {
|
||||||
|
|
||||||
|
if (result.code == '0') {
|
||||||
|
$("#btnSearch").trigger('click')
|
||||||
|
$("#excelModal").modal("hide")
|
||||||
|
Swal.fire({
|
||||||
|
title: '정상 처리되었습니다.',
|
||||||
|
icon: "success"
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: result.msg,
|
||||||
|
icon: "error"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// 엑셀 다운로드 click
|
// 엑셀 다운로드 click
|
||||||
$("#excel-download").on("click", function () {
|
$("#excel-download").on("click", function () {
|
||||||
@@ -984,6 +1191,46 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function readExcelBodyOnly(file) {
|
||||||
|
const data = await file.arrayBuffer();
|
||||||
|
const wb = XLSX.read(data, { type: "array" });
|
||||||
|
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||||
|
|
||||||
|
const rows2d = XLSX.utils.sheet_to_json(ws, {
|
||||||
|
header: 1,
|
||||||
|
defval: "",
|
||||||
|
raw: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// 첫 줄(엑셀 헤더) 제거 + 빈 행 제거
|
||||||
|
return rows2d
|
||||||
|
.slice(1)
|
||||||
|
.filter(r => r.some(v => String(v).trim() !== ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderExcelDataTable(data2d) {
|
||||||
|
// 이미 DataTable이 있으면 파괴 후 재생성(컬럼 구조가 바뀔 수 있으니)
|
||||||
|
if ($.fn.DataTable.isDataTable("#excelList")) {
|
||||||
|
$("#excelList").DataTable().clear().destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
excelTbl = $("#excelList").DataTable({
|
||||||
|
language: lang_kor,
|
||||||
|
columnDefs: [
|
||||||
|
{ className: 'text-center dt-nowrap', targets: '_all' },
|
||||||
|
],
|
||||||
|
data: data2d,
|
||||||
|
searching: false,
|
||||||
|
ordering: false,
|
||||||
|
destroy: true,
|
||||||
|
deferRender: true,
|
||||||
|
pageLength: 10,
|
||||||
|
lengthMenu: [10, 25, 50, 100],
|
||||||
|
scrollX: true,
|
||||||
|
autoWidth: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function hscp_no_enter(event) {
|
function hscp_no_enter(event) {
|
||||||
if (event.keyCode == 13) {
|
if (event.keyCode == 13) {
|
||||||
table.ajax.reload()
|
table.ajax.reload()
|
||||||
|
|||||||
BIN
public/plugin/sample/sample_apt_ground.xlsx
Normal file
BIN
public/plugin/sample/sample_apt_ground.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user