FPSMS-frontend
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 

139 lignes
4.2 KiB

  1. "use client";
  2. import { NEXT_PUBLIC_API_URL } from "@/config/api";
  3. import { clientAuthFetch } from "@/app/utils/clientAuthFetch";
  4. export interface JobOrderListItem {
  5. id: number;
  6. code: string | null;
  7. planStart: string | null;
  8. itemCode: string | null;
  9. itemName: string | null;
  10. reqQty: number | null;
  11. stockInLineId: number | null;
  12. itemId: number | null;
  13. lotNo: string | null;
  14. bagPrintedQty?: number;
  15. labelPrintedQty?: number;
  16. laserPrintedQty?: number;
  17. }
  18. export interface LaserBag2Settings {
  19. host: string;
  20. port: number;
  21. /** Comma-separated item codes; empty string = show all packaging job orders */
  22. itemCodes: string;
  23. }
  24. export interface LaserBag2SendRequest {
  25. itemId: number | null;
  26. stockInLineId: number | null;
  27. itemCode: string | null;
  28. itemName: string | null;
  29. printerIp?: string;
  30. printerPort?: number;
  31. }
  32. export interface LaserBag2SendResponse {
  33. success: boolean;
  34. message: string;
  35. payloadSent?: string | null;
  36. }
  37. /**
  38. * Uses server LASER_PRINT.itemCodes filter. Calls public GET /py/laser-job-orders (same as Python Bag2 /py/job-orders),
  39. * so it works without relying on authenticated /plastic routes.
  40. */
  41. export async function fetchLaserJobOrders(planStart: string): Promise<JobOrderListItem[]> {
  42. const base = (NEXT_PUBLIC_API_URL ?? "").replace(/\/$/, "");
  43. if (!base) {
  44. throw new Error("NEXT_PUBLIC_API_URL is not set; cannot reach API.");
  45. }
  46. const url = `${base}/py/laser-job-orders?planStart=${encodeURIComponent(planStart)}`;
  47. let res: Response;
  48. try {
  49. res = await clientAuthFetch(url, { method: "GET" });
  50. } catch (e) {
  51. const msg = e instanceof Error ? e.message : String(e);
  52. throw new Error(
  53. `無法連線 API(${url}):${msg}。請確認後端已啟動且 NEXT_PUBLIC_API_URL 指向正確(例如 http://localhost:8090/api)。`,
  54. );
  55. }
  56. if (!res.ok) {
  57. const body = await res.text().catch(() => "");
  58. throw new Error(
  59. `載入工單失敗(${res.status})${body ? `:${body.slice(0, 200)}` : ""}`,
  60. );
  61. }
  62. return res.json() as Promise<JobOrderListItem[]>;
  63. }
  64. export async function fetchLaserBag2Settings(): Promise<LaserBag2Settings> {
  65. const base = (NEXT_PUBLIC_API_URL ?? "").replace(/\/$/, "");
  66. if (!base) {
  67. throw new Error("NEXT_PUBLIC_API_URL is not set.");
  68. }
  69. const url = `${base}/plastic/laser-bag2-settings`;
  70. let res: Response;
  71. try {
  72. res = await clientAuthFetch(url, { method: "GET" });
  73. } catch (e) {
  74. const msg = e instanceof Error ? e.message : String(e);
  75. throw new Error(`無法連線至 ${url}:${msg}`);
  76. }
  77. if (!res.ok) {
  78. const body = await res.text().catch(() => "");
  79. throw new Error(`載入設定失敗(${res.status})${body ? body.slice(0, 200) : ""}`);
  80. }
  81. return res.json() as Promise<LaserBag2Settings>;
  82. }
  83. export async function sendLaserBag2Job(body: LaserBag2SendRequest): Promise<LaserBag2SendResponse> {
  84. const url = `${NEXT_PUBLIC_API_URL}/plastic/print-laser-bag2`;
  85. const res = await clientAuthFetch(url, {
  86. method: "POST",
  87. headers: { "Content-Type": "application/json" },
  88. body: JSON.stringify(body),
  89. });
  90. const data = (await res.json()) as LaserBag2SendResponse;
  91. if (!res.ok) {
  92. return data;
  93. }
  94. return data;
  95. }
  96. export interface PrinterStatusRequest {
  97. printerType: "laser";
  98. printerIp?: string;
  99. printerPort?: number;
  100. }
  101. export interface PrinterStatusResponse {
  102. connected: boolean;
  103. message: string;
  104. }
  105. export async function checkPrinterStatus(request: PrinterStatusRequest): Promise<PrinterStatusResponse> {
  106. const url = `${NEXT_PUBLIC_API_URL}/plastic/check-printer`;
  107. const res = await clientAuthFetch(url, {
  108. method: "POST",
  109. headers: { "Content-Type": "application/json" },
  110. body: JSON.stringify(request),
  111. });
  112. const data = (await res.json()) as PrinterStatusResponse;
  113. return data;
  114. }
  115. export async function patchSetting(name: string, value: string): Promise<void> {
  116. const url = `${NEXT_PUBLIC_API_URL}/settings/${encodeURIComponent(name)}`;
  117. const res = await clientAuthFetch(url, {
  118. method: "PATCH",
  119. headers: { "Content-Type": "application/json" },
  120. body: JSON.stringify({ value }),
  121. });
  122. if (!res.ok) {
  123. const t = await res.text().catch(() => "");
  124. throw new Error(t || `Failed to save setting: ${res.status}`);
  125. }
  126. }