This commit is contained in:
204
app/Controllers/Webfax/Crontab.php
Normal file
204
app/Controllers/Webfax/Crontab.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use App\Models\webfax\FaxModel;
|
||||
use App\Libraries\Qrcode;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
|
||||
class Crontab extends BaseController
|
||||
{
|
||||
/**
|
||||
* Fax 수신 이미지(tiff)를 jpg로 변경하고 Thumbnail을 만드는 작업...
|
||||
* (CLI 전용)
|
||||
*/
|
||||
public function convertedFaxImages()
|
||||
{
|
||||
// ✅ CLI 전용 보호
|
||||
if (!is_cli()) {
|
||||
throw new PageNotFoundException();
|
||||
}
|
||||
|
||||
/** @var FaxModel $faxModel */
|
||||
$faxModel = model(FaxModel::class);
|
||||
$qrCode = new Qrcode();
|
||||
|
||||
$res = $faxModel->selectFaxListNotExistsThumb();
|
||||
$fileCnt = 0;
|
||||
$receiver = 'uds_tiff';
|
||||
|
||||
if (empty($res)) {
|
||||
CLI::write('No target fax images.', 'yellow');
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($res as $row) {
|
||||
$fileCnt++;
|
||||
CLI::write("\n\n[{$fileCnt}] Processing...", 'green');
|
||||
|
||||
$mid = $row['mid'] ?? null;
|
||||
$file_name = $row['file_name'] ?? '';
|
||||
$save_path = $row['save_path'] ?? '';
|
||||
$caller_no = $row['caller_no'] ?? '';
|
||||
$callee_no = $row['callee_no'] ?? '';
|
||||
$tiff_file_name = $row['file_name'] ?? '';
|
||||
$tiff_file_size = $row['file_size'] ?? '';
|
||||
$recv_time = $row['recv_time'] ?? '';
|
||||
$save_time = $row['save_time'] ?? '';
|
||||
|
||||
if (empty($save_path) || empty($file_name)) {
|
||||
CLI::write(' - skip: save_path or file_name empty', 'yellow');
|
||||
continue;
|
||||
}
|
||||
|
||||
// ✅ pathinfo로 안전하게 처리
|
||||
$ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
|
||||
$base = pathinfo($file_name, PATHINFO_FILENAME);
|
||||
|
||||
if (!in_array($ext, ['tif', 'tiff'], true)) {
|
||||
CLI::write(" - skip: not tif/tiff ({$ext})", 'yellow');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (substr($save_path, -1) !== '/') {
|
||||
$save_path .= '/';
|
||||
}
|
||||
|
||||
$tiffPath = $save_path . $file_name;
|
||||
if (!is_file($tiffPath)) {
|
||||
CLI::write(" - skip: file not found ({$tiffPath})", 'yellow');
|
||||
continue;
|
||||
}
|
||||
|
||||
CLI::write(" - TIFF: {$tiffPath}");
|
||||
|
||||
try {
|
||||
// ✅ TIFF 다중 페이지 안전 처리
|
||||
$im = new \Imagick();
|
||||
$im->readImage($tiffPath);
|
||||
|
||||
// coalesce: 멀티프레임 안정화(특히 tiff/gif 계열)
|
||||
$frames = $im->coalesceImages();
|
||||
|
||||
$index = 0;
|
||||
foreach ($frames as $frame) {
|
||||
try {
|
||||
// 페이지별 정보
|
||||
$image_width = (int) $frame->getImageWidth();
|
||||
$image_height = (int) $frame->getImageHeight();
|
||||
$image_size = (int) $frame->getImageLength();
|
||||
|
||||
// 출력 경로
|
||||
$jpgName = "{$base}_{$index}.jpg";
|
||||
$jpgPath = $save_path . $jpgName;
|
||||
$thumbName = "{$base}_{$index}_thumb.jpg";
|
||||
$thumbPath = $save_path . $thumbName;
|
||||
|
||||
// ✅ JPG로 변환(페이지별로 frame clone 사용 권장)
|
||||
$page = clone $frame;
|
||||
|
||||
// 이미지 포맷/품질(필요시 조정)
|
||||
$page->setImageFormat('jpeg');
|
||||
$page->setImageCompression(\Imagick::COMPRESSION_JPEG);
|
||||
$page->setImageCompressionQuality(85);
|
||||
|
||||
// ✅ 리사이즈 (가로 800 제한)
|
||||
if ($image_width > 800) {
|
||||
$resize_width = 800;
|
||||
$ratio = $resize_width / max(1, $image_width);
|
||||
$resize_height = (int) round($image_height * $ratio);
|
||||
$page->resizeImage($resize_width, $resize_height, \Imagick::FILTER_LANCZOS, 1, true);
|
||||
}
|
||||
|
||||
if (!$page->writeImage($jpgPath)) {
|
||||
CLI::write(" - fail: write jpg ({$jpgPath})", 'red');
|
||||
$page->clear();
|
||||
$page->destroy();
|
||||
$index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// ✅ QR scan (실패해도 계속)
|
||||
$qrcode_data = '';
|
||||
try {
|
||||
$qrcode_data = (string) $qrCode->scan($jpgPath);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'QR scan failed: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// ✅ 썸네일은 clone으로 (원본/페이지 훼손 방지)
|
||||
$thumb = clone $page;
|
||||
$thumb->thumbnailImage(105, 80, true);
|
||||
|
||||
if (!$thumb->writeImage($thumbPath)) {
|
||||
CLI::write(" - fail: write thumb ({$thumbPath})", 'red');
|
||||
// 그래도 JPG는 만들어졌으니 다음 진행은 정책에 따라 선택
|
||||
}
|
||||
|
||||
CLI::write(" - JPG: {$jpgPath}");
|
||||
CLI::write(" - THUMB: {$thumbPath}");
|
||||
|
||||
// ✅ DB 저장 (기존 시그니처 유지)
|
||||
$faxModel->insertFaxImgs(
|
||||
$mid,
|
||||
$jpgName,
|
||||
$save_path,
|
||||
$thumbName,
|
||||
$image_width,
|
||||
$image_height,
|
||||
$image_size,
|
||||
$qrcode_data,
|
||||
$caller_no,
|
||||
$callee_no,
|
||||
$tiff_file_name,
|
||||
$tiffPath,
|
||||
$tiff_file_size,
|
||||
$recv_time,
|
||||
$save_time,
|
||||
$receiver
|
||||
);
|
||||
|
||||
// ✅ 권한 처리 (에러 숨기지 말고 로그)
|
||||
if (!@chmod($jpgPath, 0666)) {
|
||||
log_message('error', "chmod failed: {$jpgPath}");
|
||||
}
|
||||
if (!@chmod($thumbPath, 0666)) {
|
||||
log_message('error', "chmod failed: {$thumbPath}");
|
||||
}
|
||||
|
||||
log_message('debug', $jpgPath);
|
||||
log_message('debug', $thumbPath);
|
||||
|
||||
// ✅ 메모리 정리(프레임 단위)
|
||||
$thumb->clear();
|
||||
$thumb->destroy();
|
||||
$page->clear();
|
||||
$page->destroy();
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Frame 처리 실패: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// 다음 페이지
|
||||
$index++;
|
||||
}
|
||||
|
||||
// ✅ 전체 메모리 정리
|
||||
$frames->clear();
|
||||
$frames->destroy();
|
||||
|
||||
$im->clear();
|
||||
$im->destroy();
|
||||
|
||||
gc_collect_cycles();
|
||||
|
||||
CLI::write(" - done.\n", 'green');
|
||||
} catch (\Throwable $e) {
|
||||
// 기존 writeLog 사용 중이면 그걸로 교체 가능
|
||||
log_message('error', 'TIFF 처리 실패: ' . $e->getMessage());
|
||||
CLI::write(" - error: " . $e->getMessage(), 'red');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
app/Helpers/cron_helper.php
Normal file
13
app/Helpers/cron_helper.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('get_linux_hostname')) {
|
||||
/**
|
||||
* hostname을 읽어옴... $_SERVER['HOSTNAME']을 대신해서 사용하기 위함.
|
||||
*/
|
||||
function get_linux_hostname()
|
||||
{
|
||||
preg_match('/HOSTNAME=(.*)/', file_get_contents('/etc/sysconfig/network'), $network);
|
||||
list($key, $hostname) = explode('=', $network[0]);
|
||||
return $hostname;
|
||||
}
|
||||
}
|
||||
29
app/Libraries/qrcode.php
Normal file
29
app/Libraries/qrcode.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class Qrcode
|
||||
{
|
||||
|
||||
public function scan($filename)
|
||||
{
|
||||
$data = '';
|
||||
$file = urldecode($filename);
|
||||
|
||||
if (!file_exists($file)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$image = new ZBarCodeImage($file);
|
||||
$scanner = new ZBarCodeScanner();
|
||||
$barcode = $scanner->scan($image);
|
||||
if (!empty($barcode)) {
|
||||
foreach ($barcode as $code) {
|
||||
$data .= ',' . $code['data'];
|
||||
}
|
||||
if (!empty($data))
|
||||
$data = substr($data, 1);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -102,8 +102,7 @@ class AssignModel extends Model
|
||||
COUNT(*) AS cnt
|
||||
FROM result a
|
||||
INNER JOIN users b ON b.usr_sq = a.usr_sq
|
||||
INNER JOIN receipt d ON d.rcpt_sq = a.rcpt_sq
|
||||
INNER JOIN departments c ON c.dept_sq = a.dept_sq
|
||||
|
||||
|
||||
WHERE 1=1 ";
|
||||
|
||||
@@ -158,7 +157,7 @@ class AssignModel extends Model
|
||||
public function getUserList($start, $end, $data)
|
||||
{
|
||||
$sql = "SELECT
|
||||
b.usr_nm, b.usr_id, b.usr_sq, c.dept_sq, c.pdept_sq, c.depth
|
||||
b.usr_nm, b.usr_id, b.usr_sq
|
||||
, SUM(CASE WHEN a.rsrv_tm_hour IN ('00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24') THEN 1 ELSE 0 END) TODAY
|
||||
, SUM(CASE WHEN a.rsrv_tm_ap = 'AM' AND a.rsrv_tm_hour = '09' THEN 1 ELSE 0 END) AM09
|
||||
, SUM(CASE WHEN a.rsrv_tm_ap = 'AM' AND a.rsrv_tm_hour = '10' THEN 1 ELSE 0 END) AM10
|
||||
@@ -175,8 +174,7 @@ class AssignModel extends Model
|
||||
, SUM(CASE WHEN a.rsrv_tm_ap = 'PM' AND a.rsrv_tm_hour IN ('00','08','09','10','11','12','20','21','22','23','24') THEN 1 ELSE 0 END) PMETC
|
||||
FROM result a
|
||||
INNER JOIN users b ON b.usr_sq = a.usr_sq
|
||||
INNER JOIN receipt d ON d.rcpt_sq = a.rcpt_sq
|
||||
INNER JOIN departments c ON c.dept_sq = a.dept_sq
|
||||
|
||||
|
||||
WHERE 1=1 ";
|
||||
|
||||
|
||||
194
app/Models/webfax/FaxModel.php
Normal file
194
app/Models/webfax/FaxModel.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
namespace App\Models\webfax;
|
||||
|
||||
use CodeIgnier\Model;
|
||||
|
||||
class FaxModel extends Model
|
||||
{
|
||||
public function selectFaxListNotExistsThumb()
|
||||
{
|
||||
helper('cron');
|
||||
|
||||
if (!isset($_SERVER["HOSTNAME"])) {
|
||||
$_SERVER["HOSTNAME"] = get_linux_hostname();
|
||||
}
|
||||
if (empty($_SERVER["HOSTNAME"])) {
|
||||
$_SERVER["HOSTNAME"] = "unknown";
|
||||
}
|
||||
|
||||
$_SERVER["HOSTNAME"] = "unknown";
|
||||
$data = [$_SERVER["HOSTNAME"]];
|
||||
|
||||
$sql = "UPDATE uds_tiff a" .
|
||||
" SET a.etc1 = ?" .
|
||||
" WHERE NOT EXISTS (SELECT 'x' FROM fax_imgs a1 WHERE a1.mid = a.mid)" .
|
||||
" AND a.recv_time >= DATE_ADD(NOW(), INTERVAL -7 DAY)" .
|
||||
" AND a.etc1 = ''" .
|
||||
" limit 100";
|
||||
$this->db->query($sql, $data);
|
||||
|
||||
$sql = "SELECT a.mid,a.eid,a.pages,a.caller_no,a.callee_no,a.file_name,REPLACE(a.save_path, a.file_name,'') save_path,a.file_size,a.recv_time,a.save_time" .
|
||||
" FROM uds_tiff a" .
|
||||
" WHERE NOT EXISTS (SELECT 'x' FROM fax_imgs a1 WHERE a1.mid = a.mid)" .
|
||||
" AND a.recv_time >= DATE_ADD(NOW(), INTERVAL -7 DAY)" .
|
||||
" AND a.etc1 = ?";
|
||||
$query = $this->db->query($sql, $data);
|
||||
|
||||
return $query->getResultArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* tiff 이미지 jpg로 변환 및 썸네일 생성
|
||||
*/
|
||||
public function insertFaxImgs($mid, $file_name, $file_path, $thumbnail, $img_width, $img_height, $img_size, $qrcode = '', $caller_no, $callee_no, $tiff_file_name, $tiff_save_path, $tiff_file_size, $recv_time, $save_time, $receiver)
|
||||
{
|
||||
$sql = "INSERT INTO fax_imgs" .
|
||||
" (MID, file_name, file_path, thumbnail, img_width, img_height, img_size, qrcode, caller_no, callee_no, tiff_file_name, tiff_save_path, tiff_file_size, recv_time, save_time, receiver)" .
|
||||
" VALUES" .
|
||||
" (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$data = [$mid, $file_name, $file_path, $thumbnail, $img_width, $img_height, $img_size, $qrcode, $caller_no, $callee_no, $tiff_file_name, $tiff_save_path, $tiff_file_size, $recv_time, $save_time, $receiver];
|
||||
$this->db->query($sql, $data);
|
||||
}
|
||||
|
||||
public function insertFaxImgs2($mid, $file_name, $file_path, $thumbnail, $img_width, $img_height, $img_size, $qrcode = '', $caller_no, $callee_no, $tiff_file_name, $tiff_save_path, $tiff_file_size, $recv_time, $save_time, $receiver)
|
||||
{
|
||||
$sql = "INSERT INTO fax_imgs" .
|
||||
" (MID, file_name, file_path, thumbnail, img_width, img_height, img_size, qrcode, caller_no, callee_no, tiff_file_name, tiff_save_path, tiff_file_size, recv_time, save_time, receiver)" .
|
||||
" VALUES" .
|
||||
" (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$data = [$mid, $file_name, $file_path, $thumbnail, $img_width, $img_height, $img_size, $qrcode, $caller_no, $callee_no, $tiff_file_name, $tiff_save_path, $tiff_file_size, $recv_time, $save_time, $receiver];
|
||||
$this->db->query($sql, $data);
|
||||
}
|
||||
|
||||
public function selectFaxListTran()
|
||||
{
|
||||
|
||||
if (!isset($_SERVER["HOSTNAME"])) {
|
||||
$_SERVER["HOSTNAME"] = get_linux_hostname();
|
||||
}
|
||||
|
||||
$data = [$_SERVER["HOSTNAME"]];
|
||||
|
||||
$sql = "SELECT TR_MSGID, TR_TITLE, TR_SENDFAXNUM, TR_RECVFAXNUM, TR_RECVTIME, TR_FILENAMELIST" .
|
||||
" FROM FC_RECV_TRAN a" .
|
||||
" WHERE NOT EXISTS (SELECT 'x' FROM fax_imgs a1 WHERE a1.mid = a.TR_MSGID AND a1.receiver != 'uds_tiff')" .
|
||||
" AND a.TR_RECVTIME >= DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -7 DAY), '%Y%m%d%h%i%s')";
|
||||
|
||||
$query = $this->db->query($sql, $data);
|
||||
return $query->getResultArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FAX이미지를 홍보확인서에서 선택할 경우...
|
||||
*/
|
||||
public function updateImgSqOnFaxImgs($faxSq, $imgSq)
|
||||
{
|
||||
$sql = "UPDATE fax_imgs" .
|
||||
" SET img_sq = ?" .
|
||||
" WHERE fax_sq = ?";
|
||||
|
||||
$data = [$imgSq, $faxSq];
|
||||
$this->db->query($sql, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 홍보확인서를 재지정했을 경우 기존의 홍보확인서는 선택되지 않음으로 ...
|
||||
*/
|
||||
public function updateImgSqNullOnFaxImgs($imgSq)
|
||||
{
|
||||
$sql = "UPDATE fax_imgs" .
|
||||
" SET img_sq = null" .
|
||||
" WHERE img_sq = ?";
|
||||
$data = [$imgSq];
|
||||
$this->db->query($sql, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 비고를 지정한다.
|
||||
*/
|
||||
public function updateRemark($faxSq, $remark)
|
||||
{
|
||||
$sql = "UPDATE fax_imgs" .
|
||||
" SET remark = ?" .
|
||||
" WHERE fax_sq = ?";
|
||||
$data = [$remark, $faxSq];
|
||||
$this->db->query($sql, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 홍보확인서의 주소가 업데이트 되었을 경우
|
||||
* @param bigint $vr_sq receipt 테이블의 PK (rcpt_sq) 또는 v2_vrfc_req 테이블의 PK (vr_sq)
|
||||
* @param string $address_code 법정동코드
|
||||
* @param string $address2 상세주소
|
||||
* @param string $address3 기타주소
|
||||
* @param string $hscp_no 단지번호
|
||||
* @param string $hscp_nm 단지명
|
||||
*/
|
||||
public function updateAddress($vr_sq, $address_code, $address2, $address3, $hscp_no, $hscp_nm)
|
||||
{
|
||||
$data = [];
|
||||
if (!empty($address_code))
|
||||
$data['address_code'] = $address_code;
|
||||
if (!empty($address2))
|
||||
$data['address2'] = $address2;
|
||||
if (!empty($address3))
|
||||
$data['address3'] = $address3;
|
||||
// if (!empty($address4)) $data['address4'] = $address4;
|
||||
if (!empty($hscp_no))
|
||||
$data['hscp_no'] = $hscp_no;
|
||||
if (!empty($hscp_nm))
|
||||
$data['hscp_nm'] = $hscp_nm;
|
||||
|
||||
if (!empty($data)) {
|
||||
$where = [
|
||||
'vr_sq' => $vr_sq
|
||||
];
|
||||
$this->db->update('fax_imgs', $data, $where);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateAddress2($vr_sq, $address_code, $address2, $address2a, $address2b, $address3, $hscp_no, $hscp_nm)
|
||||
{
|
||||
$data = array();
|
||||
if (!empty($address_code))
|
||||
$data['address_code'] = $address_code;
|
||||
if (!empty($address2))
|
||||
$data['address2'] = $address2;
|
||||
if (!empty($address2))
|
||||
$data['address2a'] = $address2a;
|
||||
if (!empty($address2))
|
||||
$data['address2b'] = $address2b;
|
||||
if (!empty($address3))
|
||||
$data['address3'] = $address3;
|
||||
// if (!empty($address4)) $data['address4'] = $address4;
|
||||
if (!empty($hscp_no))
|
||||
$data['hscp_no'] = $hscp_no;
|
||||
if (!empty($hscp_nm))
|
||||
$data['hscp_nm'] = $hscp_nm;
|
||||
|
||||
if (!empty($data)) {
|
||||
$where = [
|
||||
'vr_sq' => $vr_sq
|
||||
];
|
||||
$this->db->update('fax_imgs', $data, $where);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 팩스건수 가져오기 -> 화면 최상단에 건수 보여줌.
|
||||
*/
|
||||
public function getFaxCount()
|
||||
{
|
||||
$sql = "SELECT
|
||||
date_format(now(), '%H') as base_time
|
||||
,(SELECT count(*) FROM uds_tiff where save_time >= concat(date_format(now(), '%Y-%m-%d %H'), ':00:00')) as enfax_count
|
||||
,(SELECT COUNT(*) FROM FC_RECV_TRAN where TR_RECVTIME >= concat(date_format(now(), '%Y%m%d%H'), '0000')) as lgfax_count
|
||||
";
|
||||
$query = $this->db->query($sql);
|
||||
|
||||
$row = $query->getRowArray();
|
||||
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user