Implement Customs API backend and frontend integration
This commit is contained in:
178
Project/Web/MachineBridge/MachineBridge.Customs.cs
Normal file
178
Project/Web/MachineBridge/MachineBridge.Customs.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using FCOMMON;
|
||||
|
||||
namespace Project.Web
|
||||
{
|
||||
public partial class MachineBridge
|
||||
{
|
||||
#region Customs API
|
||||
|
||||
/// <summary>
|
||||
/// 업체정보 목록 조회
|
||||
/// </summary>
|
||||
public string Customs_GetList(string searchKey = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
// 로그인 체크
|
||||
if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
|
||||
}
|
||||
|
||||
var connStr = Properties.Settings.Default.CS;
|
||||
using (var conn = new SqlConnection(connStr))
|
||||
{
|
||||
conn.Open();
|
||||
var cmd = new SqlCommand();
|
||||
cmd.Connection = conn;
|
||||
|
||||
// 검색 조건이 있으면 필터링
|
||||
if (string.IsNullOrEmpty(searchKey))
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
SELECT idx, grp, name, owner, ownertel, address, tel, fax, email, memo,
|
||||
wuid, wdate, uptae, staff, stafftel, name2, gcode
|
||||
FROM Customs WITH (nolock)
|
||||
WHERE gcode = @gcode
|
||||
ORDER BY name";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 여러 필드에서 검색 (fCustoms.cs의 btFind_Click 로직 참고)
|
||||
cmd.CommandText = @"
|
||||
SELECT idx, grp, name, owner, ownertel, address, tel, fax, email, memo,
|
||||
wuid, wdate, uptae, staff, stafftel, name2, gcode
|
||||
FROM Customs WITH (nolock)
|
||||
WHERE gcode = @gcode
|
||||
AND (stafftel LIKE @search
|
||||
OR grp LIKE @search
|
||||
OR name2 LIKE @search
|
||||
OR name LIKE @search
|
||||
OR owner LIKE @search
|
||||
OR address LIKE @search
|
||||
OR tel LIKE @search
|
||||
OR email LIKE @search
|
||||
OR memo LIKE @search
|
||||
OR staff LIKE @search)
|
||||
ORDER BY name";
|
||||
cmd.Parameters.Add("@search", SqlDbType.NVarChar).Value = "%" + searchKey.Replace("'", "''") + "%";
|
||||
}
|
||||
|
||||
cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode;
|
||||
|
||||
var list = new List<object>();
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
list.Add(new
|
||||
{
|
||||
idx = reader["idx"],
|
||||
grp = reader["grp"] != DBNull.Value ? reader["grp"] : "",
|
||||
name = reader["name"] != DBNull.Value ? reader["name"] : "",
|
||||
owner = reader["owner"] != DBNull.Value ? reader["owner"] : "",
|
||||
ownertel = reader["ownertel"] != DBNull.Value ? reader["ownertel"] : "",
|
||||
address = reader["address"] != DBNull.Value ? reader["address"] : "",
|
||||
tel = reader["tel"] != DBNull.Value ? reader["tel"] : "",
|
||||
fax = reader["fax"] != DBNull.Value ? reader["fax"] : "",
|
||||
email = reader["email"] != DBNull.Value ? reader["email"] : "",
|
||||
memo = reader["memo"] != DBNull.Value ? reader["memo"] : "",
|
||||
wuid = reader["wuid"],
|
||||
wdate = reader["wdate"],
|
||||
uptae = reader["uptae"] != DBNull.Value ? reader["uptae"] : "",
|
||||
staff = reader["staff"] != DBNull.Value ? reader["staff"] : "",
|
||||
stafftel = reader["stafftel"] != DBNull.Value ? reader["stafftel"] : "",
|
||||
name2 = reader["name2"] != DBNull.Value ? reader["name2"] : "",
|
||||
gcode = reader["gcode"]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "", Data = list });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message, Data = (object)null });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업체정보 상세 조회
|
||||
/// </summary>
|
||||
public string Customs_GetDetail(int idx)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 로그인 체크
|
||||
if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
|
||||
}
|
||||
|
||||
var connStr = Properties.Settings.Default.CS;
|
||||
using (var conn = new SqlConnection(connStr))
|
||||
{
|
||||
conn.Open();
|
||||
var cmd = new SqlCommand();
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = @"
|
||||
SELECT idx, grp, name, owner, ownertel, address, tel, fax, email, memo,
|
||||
wuid, wdate, uptae, staff, stafftel, name2, gcode
|
||||
FROM Customs WITH (nolock)
|
||||
WHERE idx = @idx AND gcode = @gcode";
|
||||
|
||||
cmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx;
|
||||
cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode;
|
||||
|
||||
object result = null;
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
result = new
|
||||
{
|
||||
idx = reader["idx"],
|
||||
grp = reader["grp"] != DBNull.Value ? reader["grp"] : "",
|
||||
name = reader["name"] != DBNull.Value ? reader["name"] : "",
|
||||
owner = reader["owner"] != DBNull.Value ? reader["owner"] : "",
|
||||
ownertel = reader["ownertel"] != DBNull.Value ? reader["ownertel"] : "",
|
||||
address = reader["address"] != DBNull.Value ? reader["address"] : "",
|
||||
tel = reader["tel"] != DBNull.Value ? reader["tel"] : "",
|
||||
fax = reader["fax"] != DBNull.Value ? reader["fax"] : "",
|
||||
email = reader["email"] != DBNull.Value ? reader["email"] : "",
|
||||
memo = reader["memo"] != DBNull.Value ? reader["memo"] : "",
|
||||
wuid = reader["wuid"],
|
||||
wdate = reader["wdate"],
|
||||
uptae = reader["uptae"] != DBNull.Value ? reader["uptae"] : "",
|
||||
staff = reader["staff"] != DBNull.Value ? reader["staff"] : "",
|
||||
stafftel = reader["stafftel"] != DBNull.Value ? reader["stafftel"] : "",
|
||||
name2 = reader["name2"] != DBNull.Value ? reader["name2"] : "",
|
||||
gcode = reader["gcode"]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "해당 업체 정보를 찾을 수 없습니다.", Data = (object)null });
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "", Data = result });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message, Data = (object)null });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import type {
|
||||
MachineBridgeInterface,
|
||||
BoardItem,
|
||||
MailItem,
|
||||
CustomItem,
|
||||
} from '@/types';
|
||||
|
||||
// WebView2 환경 감지
|
||||
@@ -1278,6 +1279,34 @@ class CommunicationLayer {
|
||||
return this.wsRequest<ApiResponse<MailItem[]>>('MAIL_GET_LIST', 'MAIL_LIST_DATA', { startDate, endDate, searchKey });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 업체정보 목록 조회
|
||||
* @param searchKey 검색어
|
||||
* @returns ApiResponse<CustomItem[]>
|
||||
*/
|
||||
public async getCustomsList(searchKey: string = ''): Promise<ApiResponse<CustomItem[]>> {
|
||||
if (isWebView && machine) {
|
||||
const result = await machine.Customs_GetList(searchKey);
|
||||
return JSON.parse(result);
|
||||
} else {
|
||||
return this.wsRequest<ApiResponse<CustomItem[]>>('CUSTOMS_GET_LIST', 'CUSTOMS_LIST_DATA', { searchKey });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 업체정보 상세 조회
|
||||
* @param idx 업체 인덱스
|
||||
* @returns ApiResponse<CustomItem>
|
||||
*/
|
||||
public async getCustomsDetail(idx: number): Promise<ApiResponse<CustomItem>> {
|
||||
if (isWebView && machine) {
|
||||
const result = await machine.Customs_GetDetail(idx);
|
||||
return JSON.parse(result);
|
||||
} else {
|
||||
return this.wsRequest<ApiResponse<CustomItem>>('CUSTOMS_GET_DETAIL', 'CUSTOMS_DETAIL_DATA', { idx });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const comms = new CommunicationLayer();
|
||||
|
||||
@@ -1,21 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Building, Search, RefreshCw } from 'lucide-react';
|
||||
|
||||
// 임시 타입 정의 (실제 타입은 백엔드에 맞게 수정 필요)
|
||||
interface CustomItem {
|
||||
idx: number;
|
||||
ccode: string;
|
||||
cname: string;
|
||||
gubun: string;
|
||||
addr: string;
|
||||
tel: string;
|
||||
fax: string;
|
||||
email: string;
|
||||
ceo: string;
|
||||
busino: string;
|
||||
uptae: string;
|
||||
jongmok: string;
|
||||
}
|
||||
import { comms } from '@/communication';
|
||||
import type { CustomItem } from '@/types';
|
||||
|
||||
export function Customs() {
|
||||
const [customsList, setCustomsList] = useState<CustomItem[]>([]);
|
||||
@@ -29,19 +15,18 @@ export function Customs() {
|
||||
const loadData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// TODO: 실제 API 호출로 변경 필요
|
||||
// const response = await comms.getCustomsList(searchKey);
|
||||
// if (response.Success && response.Data) {
|
||||
// setCustomsList(response.Data);
|
||||
// }
|
||||
|
||||
// 임시 데이터
|
||||
console.log('업체정보 조회 (구현 필요):', { searchKey });
|
||||
alert('업체정보 API가 아직 구현되지 않았습니다.');
|
||||
setCustomsList([]);
|
||||
const response = await comms.getCustomsList(searchKey);
|
||||
if (response.Success && response.Data) {
|
||||
setCustomsList(response.Data);
|
||||
} else {
|
||||
console.error('업체정보 조회 실패:', response.Message);
|
||||
alert(response.Message || '업체정보 조회에 실패했습니다.');
|
||||
setCustomsList([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('업체정보 로드 오류:', error);
|
||||
alert('데이터를 불러오는 중 오류가 발생했습니다.');
|
||||
setCustomsList([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -63,7 +48,7 @@ export function Customs() {
|
||||
value={searchKey}
|
||||
onChange={(e) => setSearchKey(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
|
||||
placeholder="업체명, 사업자번호, 대표자 등"
|
||||
placeholder="업체명, 대표자, 전화번호, 이메일, 담당자 등"
|
||||
className="flex-1 h-10 bg-white/20 border border-white/30 rounded-lg px-3 text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400"
|
||||
/>
|
||||
</div>
|
||||
@@ -115,16 +100,21 @@ export function Customs() {
|
||||
>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex-1 min-w-0">
|
||||
<h4 className="text-white font-medium mb-1">{item.cname}</h4>
|
||||
<div className="flex items-center gap-4 text-white/60 text-sm">
|
||||
<div>대표: {item.ceo}</div>
|
||||
<div>사업자: {item.busino}</div>
|
||||
<div>업태: {item.uptae}</div>
|
||||
<h4 className="text-white font-medium mb-1">
|
||||
{item.name}
|
||||
{item.name2 && <span className="text-white/60 text-sm ml-2">({item.name2})</span>}
|
||||
</h4>
|
||||
<div className="flex items-center gap-4 text-white/60 text-sm flex-wrap">
|
||||
{item.grp && <div>구분: {item.grp}</div>}
|
||||
{item.owner && <div>대표: {item.owner}</div>}
|
||||
{item.uptae && <div>업태: {item.uptae}</div>}
|
||||
{item.address && <div>{item.address}</div>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-end gap-1 flex-shrink-0 text-white/60 text-sm">
|
||||
<div>{item.tel}</div>
|
||||
<div>{item.email}</div>
|
||||
{item.tel && <div>{item.tel}</div>}
|
||||
{item.email && <div>{item.email}</div>}
|
||||
{item.staff && <div>담당: {item.staff}</div>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -462,6 +462,10 @@ export interface MachineBridgeInterface {
|
||||
|
||||
// Mail API (메일 발신 내역)
|
||||
Mail_GetList(startDate: string, endDate: string, searchKey: string): Promise<string>;
|
||||
|
||||
// Customs API (업체정보)
|
||||
Customs_GetList(searchKey: string): Promise<string>;
|
||||
Customs_GetDetail(idx: number): Promise<string>;
|
||||
}
|
||||
|
||||
// 사용자 권한 정보 타입
|
||||
@@ -859,3 +863,24 @@ export interface MailItem {
|
||||
cate: string;
|
||||
wdate: string | null;
|
||||
}
|
||||
|
||||
// 업체정보 타입
|
||||
export interface CustomItem {
|
||||
idx: number;
|
||||
grp: string;
|
||||
name: string;
|
||||
owner: string;
|
||||
ownertel: string;
|
||||
address: string;
|
||||
tel: string;
|
||||
fax: string;
|
||||
email: string;
|
||||
memo: string;
|
||||
wuid: string;
|
||||
wdate: string;
|
||||
uptae: string;
|
||||
staff: string;
|
||||
stafftel: string;
|
||||
name2: string;
|
||||
gcode: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user