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,
|
MachineBridgeInterface,
|
||||||
BoardItem,
|
BoardItem,
|
||||||
MailItem,
|
MailItem,
|
||||||
|
CustomItem,
|
||||||
} from '@/types';
|
} from '@/types';
|
||||||
|
|
||||||
// WebView2 환경 감지
|
// WebView2 환경 감지
|
||||||
@@ -1278,6 +1279,34 @@ class CommunicationLayer {
|
|||||||
return this.wsRequest<ApiResponse<MailItem[]>>('MAIL_GET_LIST', 'MAIL_LIST_DATA', { startDate, endDate, searchKey });
|
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();
|
export const comms = new CommunicationLayer();
|
||||||
|
|||||||
@@ -1,21 +1,7 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Building, Search, RefreshCw } from 'lucide-react';
|
import { Building, Search, RefreshCw } from 'lucide-react';
|
||||||
|
import { comms } from '@/communication';
|
||||||
// 임시 타입 정의 (실제 타입은 백엔드에 맞게 수정 필요)
|
import type { CustomItem } from '@/types';
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Customs() {
|
export function Customs() {
|
||||||
const [customsList, setCustomsList] = useState<CustomItem[]>([]);
|
const [customsList, setCustomsList] = useState<CustomItem[]>([]);
|
||||||
@@ -29,19 +15,18 @@ export function Customs() {
|
|||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
// TODO: 실제 API 호출로 변경 필요
|
const response = await comms.getCustomsList(searchKey);
|
||||||
// const response = await comms.getCustomsList(searchKey);
|
if (response.Success && response.Data) {
|
||||||
// if (response.Success && response.Data) {
|
setCustomsList(response.Data);
|
||||||
// setCustomsList(response.Data);
|
} else {
|
||||||
// }
|
console.error('업체정보 조회 실패:', response.Message);
|
||||||
|
alert(response.Message || '업체정보 조회에 실패했습니다.');
|
||||||
// 임시 데이터
|
|
||||||
console.log('업체정보 조회 (구현 필요):', { searchKey });
|
|
||||||
alert('업체정보 API가 아직 구현되지 않았습니다.');
|
|
||||||
setCustomsList([]);
|
setCustomsList([]);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('업체정보 로드 오류:', error);
|
console.error('업체정보 로드 오류:', error);
|
||||||
alert('데이터를 불러오는 중 오류가 발생했습니다.');
|
alert('데이터를 불러오는 중 오류가 발생했습니다.');
|
||||||
|
setCustomsList([]);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -63,7 +48,7 @@ export function Customs() {
|
|||||||
value={searchKey}
|
value={searchKey}
|
||||||
onChange={(e) => setSearchKey(e.target.value)}
|
onChange={(e) => setSearchKey(e.target.value)}
|
||||||
onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
|
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"
|
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>
|
</div>
|
||||||
@@ -115,16 +100,21 @@ export function Customs() {
|
|||||||
>
|
>
|
||||||
<div className="flex items-center justify-between gap-4">
|
<div className="flex items-center justify-between gap-4">
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<h4 className="text-white font-medium mb-1">{item.cname}</h4>
|
<h4 className="text-white font-medium mb-1">
|
||||||
<div className="flex items-center gap-4 text-white/60 text-sm">
|
{item.name}
|
||||||
<div>대표: {item.ceo}</div>
|
{item.name2 && <span className="text-white/60 text-sm ml-2">({item.name2})</span>}
|
||||||
<div>사업자: {item.busino}</div>
|
</h4>
|
||||||
<div>업태: {item.uptae}</div>
|
<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>
|
</div>
|
||||||
<div className="flex flex-col items-end gap-1 flex-shrink-0 text-white/60 text-sm">
|
<div className="flex flex-col items-end gap-1 flex-shrink-0 text-white/60 text-sm">
|
||||||
<div>{item.tel}</div>
|
{item.tel && <div>{item.tel}</div>}
|
||||||
<div>{item.email}</div>
|
{item.email && <div>{item.email}</div>}
|
||||||
|
{item.staff && <div>담당: {item.staff}</div>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -462,6 +462,10 @@ export interface MachineBridgeInterface {
|
|||||||
|
|
||||||
// Mail API (메일 발신 내역)
|
// Mail API (메일 발신 내역)
|
||||||
Mail_GetList(startDate: string, endDate: string, searchKey: string): Promise<string>;
|
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;
|
cate: string;
|
||||||
wdate: string | null;
|
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