Merge branch 'main' of https://gitea.o2o.kr/Negosium/o2o-negosium
This commit is contained in:
commit
b65de5a5f2
@ -29,6 +29,7 @@ import {
|
||||
normalizeQuotationStatus,
|
||||
buildBidSummary,
|
||||
mapServerSessionView,
|
||||
sessionStatusLabel,
|
||||
mapServerCardView,
|
||||
} from '../types';
|
||||
|
||||
@ -459,7 +460,7 @@ export function QuotationDetailDrawer({
|
||||
<TableCell className="p-3 text-center">
|
||||
<span
|
||||
className={`inline-flex px-2 py-0.5 rounded-full text-[10px] font-bold ${
|
||||
sess.status === '협상종료' || sess.status === 'COMPLETED'
|
||||
sess.status === '협상완료' || sess.status === 'COMPLETED'
|
||||
? 'bg-blue-100 text-blue-800 dark:bg-blue-950/20 dark:text-blue-300'
|
||||
: sess.status === '협상거부' || sess.status === 'REJECTED'
|
||||
? 'bg-red-100 text-red-800 dark:bg-red-950/20 dark:text-red-300'
|
||||
@ -561,7 +562,7 @@ export function QuotationDetailDrawer({
|
||||
{serverSessions.map((sd) => {
|
||||
const isSelected = sd.session_id === effectiveSessionId;
|
||||
const name = partners.find((p) => p.id === sd.supplier_id)?.name || sd.supplier_id;
|
||||
const statusLabel = sd.status === 2 ? '협상종료' : sd.status === 3 ? '협상거부' : '협상중';
|
||||
const statusLabel = sessionStatusLabel(sd.status);
|
||||
return (
|
||||
<button
|
||||
key={sd.session_id}
|
||||
@ -576,7 +577,7 @@ export function QuotationDetailDrawer({
|
||||
className={`text-[9px] font-bold px-1.5 py-0.5 rounded ${
|
||||
statusLabel === '협상거부'
|
||||
? 'bg-rose-100 text-rose-800 dark:bg-rose-950/30 dark:text-rose-300'
|
||||
: statusLabel === '협상종료'
|
||||
: statusLabel === '협상완료'
|
||||
? 'bg-blue-100 text-blue-800 dark:bg-blue-950/30 dark:text-blue-300'
|
||||
: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-950/30 dark:text-emerald-300'
|
||||
}`}
|
||||
|
||||
@ -172,9 +172,11 @@ export function useQuotations() {
|
||||
try {
|
||||
const res = await createQuotationMutation.mutateAsync({ data: payload });
|
||||
const qtId = res?.quotation?.qt_id ?? null;
|
||||
// 서버가 result.success=false 거나 qt_id 가 없으면 실패로 처리(HTTP 200 이어도). 모달은 그대로 유지.
|
||||
// 에러는 응답 패킷 규약(result.success/code/desc + msg)대로 표시한다. HTTP 200 이어도 success=false면 실패.
|
||||
if (!res?.result?.success || !qtId) {
|
||||
showToast(`견적 생성 실패: ${res?.result?.desc ?? '서버 오류'}`, 'error');
|
||||
const reason = res?.msg ?? res?.result?.desc ?? '서버 오류';
|
||||
const code = res?.result?.code;
|
||||
showToast(`견적 생성 실패${code ? ` [${code}]` : ''}: ${reason}`, 'error');
|
||||
return null;
|
||||
}
|
||||
// 목록 재조회가 끝나야 새 견적이 정본 목록에 들어온다(상세 자동오픈이 그 행을 찾을 수 있게).
|
||||
|
||||
@ -259,7 +259,18 @@ export function buildSessions(
|
||||
|
||||
// ── 서버 연동 매퍼(negotiation.sessions / chats / 사용 카드) ──────────────
|
||||
|
||||
const SESSION_STATUS_LABEL: Record<number, string> = { 1: '협상중', 2: '협상종료', 3: '협상거부' };
|
||||
// 세션상태 코드→라벨. 서버 /v1/enums(session_status) · SHARED_ENUMS.md 5-state 와 동일해야 한다.
|
||||
// (정본은 서버 enum — 여기 값은 그걸 미러링한 것이며 드리프트 시 서버 기준으로 맞춘다.)
|
||||
export const SESSION_STATUS_LABEL: Record<number, string> = {
|
||||
1: '협상생성',
|
||||
2: '협상중',
|
||||
3: '협상완료',
|
||||
4: '미참여',
|
||||
5: '협상거부',
|
||||
};
|
||||
// 코드→라벨 단일 진입점. 미정의 코드는 코드 문자열 그대로.
|
||||
export const sessionStatusLabel = (code?: number | null): string =>
|
||||
(code != null ? SESSION_STATUS_LABEL[code] : undefined) ?? String(code ?? '');
|
||||
const DELIVERY_TYPE_LABEL: Record<number, string> = { 1: '협력사배송', 2: '지정택배배송', 3: '픽업배송' };
|
||||
|
||||
// ISO 문자열 → 'YYYY-MM-DD HH:mm'. 빈 값/파싱 실패는 '-'.
|
||||
|
||||
@ -285,7 +285,7 @@ export interface ChatMessage {
|
||||
export interface ChatSession {
|
||||
id: string; // matches supplier_id (or supplier.supplier_id)
|
||||
partnerName: string;
|
||||
status: 'NEGOTIATING' | 'COMPLETED' | 'REJECTED' | '협상생성' | '협상중' | '협상종료' | '미참여' | '협상거부';
|
||||
status: 'NEGOTIATING' | 'COMPLETED' | 'REJECTED' | '협상생성' | '협상중' | '협상완료' | '미참여' | '협상거부';
|
||||
currentBid: number;
|
||||
bidTime: string;
|
||||
messages: ChatMessage[];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user