FPSMS-frontend
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 

732 Zeilen
22 KiB

  1. "use server";
  2. import { BASE_API_URL } from "@/config/api";
  3. // import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
  4. import { revalidateTag } from "next/cache";
  5. import { cache } from "react";
  6. import { serverFetch, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
  7. import { QcItemResult } from "../settings/qcItem";
  8. import { RecordsRes } from "../utils";
  9. import { DoResult } from ".";
  10. import { GridRowId, GridRowSelectionModel } from "@mui/x-data-grid";
  11. import { GET } from "../auth/[...nextauth]/route";
  12. import { stringify } from "querystring";
  13. import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";
  14. import type {
  15. DoReplenishmentRecord,
  16. SubmitDoReplenishmentLineRequest,
  17. } from "./replenishmentTypes";
  18. export type { DoReplenishmentRecord, SubmitDoReplenishmentLineRequest };
  19. export interface CreateConsoDoInput {
  20. ids: GridRowSelectionModel;
  21. }
  22. export interface DoDetail {
  23. id: number;
  24. code: string;
  25. supplierCode: string;
  26. shopCode: string;
  27. shopName: string;
  28. currencyCode: string;
  29. orderDate: string;
  30. estimatedArrivalDate: string;
  31. completeDate: string;
  32. status: string;
  33. /** 加單 DO */
  34. isExtra?: boolean;
  35. /** 揀貨員名稱(delivery_order_pick_order.handlerName) */
  36. handlerName?: string | null;
  37. /** 來源 DO 車線 */
  38. truckLaneCode?: string | null;
  39. deliveryOrderLines: DoDetailLine[];
  40. }
  41. export interface DoDetailLine {
  42. id: number;
  43. itemNo: string;
  44. qty: number;
  45. /** Sum of stock_out_line qty for linked pick order line; falls back to qty. */
  46. actualShippedQty?: number;
  47. price: number;
  48. status: string;
  49. itemName?: string;
  50. uomCode?: string;
  51. uom?: string;
  52. shortUom?: string;
  53. /** AVAILABLE lot lines: sum(in - out - hold), same unit as DO line qty. */
  54. stockQty?: number;
  55. /** `available` | `insufficient` */
  56. availableStatus?: string;
  57. }
  58. export interface DoSearchAll {
  59. id: number;
  60. code: string;
  61. status: string;
  62. estimatedArrivalDate: number[];
  63. orderDate: number[];
  64. supplierName: string;
  65. shopName: string;
  66. shopAddress?: string;
  67. isExtra?: boolean;
  68. truckLanceCode?: string | null;
  69. }
  70. export interface DoSearchLiteResponse {
  71. records: DoSearchAll[];
  72. total: number;
  73. }
  74. export interface ReleaseDoRequest {
  75. id: number;
  76. }
  77. export interface ReleaseDoResponse {
  78. id: number;
  79. entity: { status: string }
  80. }
  81. export interface AssignByStoreRequest {
  82. storeId: string; // "2/F" or "4/F"
  83. assignTo: number;
  84. }
  85. export interface AssignByStoreResponse {
  86. id: number;
  87. code: string;
  88. name: string;
  89. type: string;
  90. message: string;
  91. errorPosition: string;
  92. entity: any;
  93. }
  94. export interface PrintDeliveryNoteRequest{
  95. doPickOrderId: number;
  96. printerId: number;
  97. printQty: number;
  98. numOfCarton: number;
  99. isDraft: boolean;
  100. }
  101. export interface PrintDeliveryNoteResponse{
  102. success: boolean;
  103. message?: string
  104. }
  105. export interface PrintDNLabelsRequest{
  106. doPickOrderId: number;
  107. printerId: number;
  108. printQty: number;
  109. numOfCarton: number;
  110. }
  111. export interface PrintDNLabelsReprintRequest{
  112. doPickOrderId: number;
  113. printerId: number;
  114. printQty: number;
  115. fromCarton: number;
  116. toCarton: number;
  117. totalCartonsOnShipment: number;
  118. }
  119. export interface PrintDNLabelsRespone{
  120. success: boolean;
  121. message?: string
  122. }
  123. export interface BatchReleaseRequest {
  124. ids: number[];
  125. }
  126. export interface BatchReleaseResponse {
  127. success: boolean;
  128. message?: string
  129. }
  130. export interface getTicketReleaseTable {
  131. id: number;
  132. storeId: string | null;
  133. ticketNo: string | null;
  134. pickOrderId: number | null;
  135. doOrderId: number | null;
  136. pickOrderCode: string | null;
  137. deliveryOrderCode: string | null;
  138. loadingSequence: number | null;
  139. ticketStatus: string | null;
  140. truckId: number | null;
  141. truckDepartureTime: string | null;
  142. shopId: number | null;
  143. handledBy: number | null;
  144. ticketReleaseTime: string | null;
  145. ticketCompleteDateTime: string | null;
  146. truckLanceCode: string | null;
  147. shopCode: string | null;
  148. shopName: string | null;
  149. requiredDeliveryDate: string | null;
  150. handlerName: string | null;
  151. numberOfFGItems: number;
  152. /** 進行中 do_pick_order 為 true,才可呼叫 force-complete / revert-assignment(id 為 do_pick_order 主鍵) */
  153. isActiveDoPickOrder?: boolean;
  154. }
  155. export interface WorkbenchTicketReleaseTable {
  156. deliveryOrderPickOrderId: number;
  157. storeId: string | null;
  158. ticketNo: string | null;
  159. loadingSequence: number | null;
  160. ticketStatus: string | null;
  161. truckDepartureTime: string | null;
  162. handledBy: number | null;
  163. ticketReleaseTime: string | null;
  164. ticketCompleteDateTime: string | null;
  165. truckLanceCode: string | null;
  166. shopCode: string | null;
  167. shopName: string | null;
  168. requiredDeliveryDate: string | null;
  169. handlerName: string | null;
  170. numberOfFGItems: number;
  171. isActiveWorkbenchTicket?: boolean;
  172. }
  173. export interface WorkbenchTicketOpResponse {
  174. id: number | null;
  175. name: string | null;
  176. code: string;
  177. type: string | null;
  178. message: string | null;
  179. errorPosition: string | null;
  180. entity?: any;
  181. }
  182. export interface TruckScheduleDashboardItem {
  183. storeId: string | null;
  184. truckId: number | null;
  185. truckLanceCode: string | null;
  186. truckDepartureTime: string | number[] | null;
  187. numberOfShopsToServe: number;
  188. numberOfPickTickets: number;
  189. totalItemsToPick: number;
  190. numberOfTicketsReleased: number;
  191. firstTicketStartTime: string | number[] | null;
  192. numberOfTicketsCompleted: number;
  193. lastTicketEndTime: string | number[] | null;
  194. pickTimeTakenMinutes: number | null;
  195. }
  196. export interface SearchDeliveryOrderInfoRequest {
  197. code: string;
  198. shopName: string;
  199. status: string;
  200. orderStartDate: string;
  201. orderEndDate: string;
  202. estArrStartDate: string;
  203. estArrEndDate: string;
  204. pageSize: number;
  205. pageNum: number;
  206. }
  207. export interface SearchDeliveryOrderInfoResponse {
  208. records: DeliveryOrderInfo[];
  209. total: number;
  210. }
  211. export interface DeliveryOrderInfo {
  212. id: number;
  213. code: string;
  214. shopName: string;
  215. supplierName: string; // 改为必需字段
  216. status: string;
  217. orderDate: string;
  218. estimatedArrivalDate: string;
  219. deliveryOrderLines: DoDetailLine[];
  220. }
  221. export const fetchDoRecordByPage = cache(async (data?: SearchDeliveryOrderInfoRequest) => {
  222. const queryStr = convertObjToURLSearchParams(data)
  223. console.log("queryStr", queryStr)
  224. const response = serverFetchJson<SearchDeliveryOrderInfoResponse>(
  225. `${BASE_API_URL}/jo/getRecordByPage?${queryStr}`,
  226. {
  227. method: "GET",
  228. headers: { "Content-Type": "application/json" },
  229. next: {
  230. tags: ["jos"]
  231. }
  232. }
  233. )
  234. return response
  235. })
  236. export const fetchTicketReleaseTable = cache(async (startDate: string, endDate: string)=> {
  237. return await serverFetchJson<getTicketReleaseTable[]>(
  238. `${BASE_API_URL}/doPickOrder/ticket-release-table/${startDate}&${endDate}`,
  239. {
  240. method: "GET",
  241. }
  242. );
  243. });
  244. export const fetchWorkbenchTicketReleaseTable = cache(async (startDate: string, endDate: string)=> {
  245. return await serverFetchJson<WorkbenchTicketReleaseTable[]>(
  246. `${BASE_API_URL}/doPickOrder/workbench/ticket-release-table/${startDate}&${endDate}`,
  247. {
  248. method: "GET",
  249. }
  250. );
  251. });
  252. export async function forceCompleteWorkbenchTicket(
  253. deliveryOrderPickOrderId: number,
  254. ): Promise<WorkbenchTicketOpResponse> {
  255. return await serverFetchJson<WorkbenchTicketOpResponse>(
  256. `${BASE_API_URL}/doPickOrder/workbench/force-complete/${deliveryOrderPickOrderId}`,
  257. {
  258. method: "POST",
  259. headers: { "Content-Type": "application/json" },
  260. },
  261. );
  262. }
  263. export async function revertWorkbenchTicketAssignment(
  264. deliveryOrderPickOrderId: number,
  265. ): Promise<WorkbenchTicketOpResponse> {
  266. return await serverFetchJson<WorkbenchTicketOpResponse>(
  267. `${BASE_API_URL}/doPickOrder/workbench/revert-assignment/${deliveryOrderPickOrderId}`,
  268. {
  269. method: "POST",
  270. headers: { "Content-Type": "application/json" },
  271. },
  272. );
  273. }
  274. export const fetchTruckScheduleDashboard = cache(async (date?: string) => {
  275. const url = date
  276. ? `${BASE_API_URL}/doPickOrder/truck-schedule-dashboard?date=${date}`
  277. : `${BASE_API_URL}/doPickOrder/truck-schedule-dashboard`;
  278. return await serverFetchJson<TruckScheduleDashboardItem[]>(
  279. url,
  280. {
  281. method: "GET",
  282. }
  283. );
  284. });
  285. export const startBatchReleaseAsyncSingle = cache(async (data: { doId: number; userId: number }) => {
  286. const { doId, userId } = data;
  287. return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
  288. `${BASE_API_URL}/doPickOrder/batch-release/async-single?userId=${userId}`,
  289. {
  290. method: "POST",
  291. body: JSON.stringify(doId),
  292. headers: { "Content-Type": "application/json" },
  293. }
  294. );
  295. });
  296. export const startBatchReleaseAsync = cache(async (data: { ids: number[]; userId: number }) => {
  297. const { ids, userId } = data;
  298. return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
  299. `${BASE_API_URL}/doPickOrder/batch-release/async?userId=${userId}`,
  300. {
  301. method: "POST",
  302. body: JSON.stringify(ids),
  303. headers: { "Content-Type": "application/json" },
  304. }
  305. );
  306. });
  307. export const getBatchReleaseProgress = cache(async (jobId: string) => {
  308. return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
  309. `${BASE_API_URL}/doPickOrder/batch-release/progress/${jobId}`,
  310. { method: "GET" }
  311. );
  312. });
  313. export const assignPickOrderByStore = cache(async (data: AssignByStoreRequest) => {
  314. return await serverFetchJson<AssignByStoreResponse>(`${BASE_API_URL}/doPickOrder/assign-by-store`,
  315. {
  316. method: "POST",
  317. body: JSON.stringify(data),
  318. headers: { "Content-Type": "application/json" },
  319. })
  320. })
  321. export const releaseAssignedPickOrderByStore = cache(async (data: AssignByStoreRequest) => {
  322. return await serverFetchJson<AssignByStoreResponse>(`${BASE_API_URL}/doPickOrder/release-assigned-by-store`,
  323. {
  324. method: "POST",
  325. body: JSON.stringify(data),
  326. headers: { "Content-Type": "application/json" },
  327. })
  328. })
  329. export async function releaseDo(input: ReleaseDoRequest) {
  330. const response = await serverFetchJson<ReleaseDoResponse>(`${BASE_API_URL}/do/release`, {
  331. method: 'POST',
  332. body: JSON.stringify(input),
  333. headers: {
  334. 'Content-Type': 'application/json',
  335. },
  336. });
  337. revalidateTag('do');
  338. return response;
  339. }
  340. export const preloadDo = () => {
  341. fetchDoList();
  342. };
  343. export const fetchDoList = cache(async () => {
  344. return serverFetchJson<DoResult[]>(`${BASE_API_URL}/do/list`, {
  345. next: { tags: ["doList"] },
  346. });
  347. });
  348. export const fetchDoDetail = cache(async (id: number) => {
  349. return serverFetchJson<DoDetail>(`${BASE_API_URL}/do/detail/${id}`, {
  350. method: "GET",
  351. headers: { "Content-Type": "application/json" },
  352. next: {
  353. tags: ["doDetail"]
  354. }
  355. });
  356. });
  357. export async function fetchDoSearch(
  358. code: string,
  359. shopName: string,
  360. status: string,
  361. orderStartDate: string,
  362. orderEndDate: string,
  363. estArrStartDate: string,
  364. estArrEndDate: string,
  365. pageNum?: number,
  366. pageSize?: number,
  367. truckLanceCode?: string,
  368. /** 後端:All/null 為全部;2F/4F 依供應商白名單篩選 */
  369. floor?: string | null,
  370. /** null:不篩;true/false:只顯示加單或非加單 DO */
  371. isExtra?: boolean | null,
  372. ): Promise<DoSearchLiteResponse> {
  373. // 构建请求体
  374. const requestBody: any = {
  375. code: code || null,
  376. shopName: shopName || null,
  377. status: status || null,
  378. estimatedArrivalDate: estArrStartDate || null, // 使用单个日期字段
  379. truckLanceCode: truckLanceCode || null,
  380. pageNum: pageNum || 1,
  381. pageSize: pageSize || 10,
  382. floor: floor && floor !== "All" ? floor : null,
  383. ...(isExtra !== undefined && isExtra !== null ? { isExtra } : {}),
  384. };
  385. // 如果日期不为空,转换为 LocalDateTime 格式
  386. if (estArrStartDate) {
  387. requestBody.estimatedArrivalDate = estArrStartDate; // 格式: "2026-01-19T00:00:00"
  388. } else {
  389. requestBody.estimatedArrivalDate = null;
  390. }
  391. /** v2:車線正規化、未指派合併、分批掃描(後端 /do/search-do-lite-v2) */
  392. const data = await serverFetchJson<DoSearchLiteResponse>(
  393. `${BASE_API_URL}/do/search-do-lite-v2`,
  394. {
  395. method: "POST",
  396. headers: { "Content-Type": "application/json" },
  397. body: JSON.stringify(requestBody),
  398. },
  399. );
  400. return data;
  401. }
  402. export async function fetchDoSearchList(
  403. code: string,
  404. shopName: string,
  405. status: string,
  406. orderStartDate: string,
  407. orderEndDate: string,
  408. etaFrom: string,
  409. etaTo: string,
  410. page = 0,
  411. size = 500
  412. ): Promise<DoSearchAll[]> {
  413. const params = new URLSearchParams();
  414. if (code) params.append("code", code);
  415. if (shopName) params.append("shopName", shopName);
  416. if (status) params.append("status", status);
  417. if (orderStartDate) params.append("orderFrom", orderStartDate);
  418. if (orderEndDate) params.append("orderTo", orderEndDate);
  419. if (etaFrom) params.append("etaFrom", etaFrom);
  420. if (etaTo) params.append("etaTo", etaTo);
  421. params.append("page", String(page));
  422. params.append("size", String(size));
  423. const res = await fetch(`/api/delivery-order/search-do-list?${params.toString()}`);
  424. const pageData = await res.json(); // Spring Page 结构
  425. return pageData.content; // 前端继续沿用你原来的 client-side 分页逻辑
  426. }
  427. export async function printDN(request: PrintDeliveryNoteRequest){
  428. const params = new URLSearchParams();
  429. params.append('doPickOrderId', request.doPickOrderId.toString());
  430. params.append('printerId', request.printerId.toString());
  431. if (request.printQty !== null && request.printQty !== undefined) {
  432. params.append('printQty', request.printQty.toString());
  433. }
  434. params.append('numOfCarton', request.numOfCarton.toString());
  435. params.append('isDraft', request.isDraft.toString());
  436. try {
  437. const response = await serverFetch(`${BASE_API_URL}/do/print-DN?${params.toString()}`, {
  438. method: "GET",
  439. });
  440. if (response.ok) {
  441. return { success: true, message: "Print job sent successfully (DN)" } as PrintDeliveryNoteResponse;
  442. }
  443. const errorText = await response.text();
  444. console.error("Print DN error:", errorText);
  445. return {
  446. success: false,
  447. message: "No data found for this pick order."
  448. } as PrintDeliveryNoteResponse;
  449. } catch (error) {
  450. console.error("Error in printDN:", error);
  451. return {
  452. success: false,
  453. message: "No data found for this pick order."
  454. } as PrintDeliveryNoteResponse;
  455. }
  456. }
  457. export async function printDNLabels(request: PrintDNLabelsRequest){
  458. const params = new URLSearchParams();
  459. params.append('doPickOrderId', request.doPickOrderId.toString());
  460. params.append('printerId', request.printerId.toString());
  461. if (request.printQty !== null && request.printQty !== undefined) {
  462. params.append('printQty', request.printQty.toString());
  463. }
  464. params.append('numOfCarton', request.numOfCarton.toString());
  465. const response = await serverFetchWithNoContent(`${BASE_API_URL}/do/print-DNLabels?${params.toString()}`,{
  466. method: "GET"
  467. });
  468. return { success: true, message: "Print job sent successfully (labels)"} as PrintDeliveryNoteResponse
  469. }
  470. export async function printDNLabelsReprint(request: PrintDNLabelsReprintRequest){
  471. const params = new URLSearchParams();
  472. params.append('doPickOrderId', request.doPickOrderId.toString());
  473. params.append('printerId', request.printerId.toString());
  474. if (request.printQty !== null && request.printQty !== undefined) {
  475. params.append('printQty', request.printQty.toString());
  476. }
  477. params.append('fromCarton', request.fromCarton.toString());
  478. params.append('toCarton', request.toCarton.toString());
  479. params.append('totalCartonsOnShipment', request.totalCartonsOnShipment.toString());
  480. await serverFetchWithNoContent(`${BASE_API_URL}/do/print-DNLabels-reprint?${params.toString()}`,{
  481. method: "GET"
  482. });
  483. return { success: true, message: "Print job sent successfully (reprint labels)"} as PrintDeliveryNoteResponse
  484. }
  485. export interface PrintWorkbenchDeliveryNoteRequest{
  486. deliveryOrderPickOrderId: number;
  487. printerId: number;
  488. printQty: number;
  489. numOfCarton: number;
  490. isDraft: boolean;
  491. }
  492. export interface PrintWorkbenchDNLabelsRequest{
  493. deliveryOrderPickOrderId: number;
  494. printerId: number;
  495. printQty: number;
  496. numOfCarton: number;
  497. blankCartonNumber?: boolean;
  498. }
  499. export interface PrintWorkbenchDNLabelsReprintRequest{
  500. deliveryOrderPickOrderId: number;
  501. printerId: number;
  502. printQty: number;
  503. fromCarton: number;
  504. toCarton: number;
  505. totalCartonsOnShipment: number;
  506. }
  507. export async function printDNWorkbench(request: PrintWorkbenchDeliveryNoteRequest){
  508. const params = new URLSearchParams();
  509. params.append("doPickOrderId", request.deliveryOrderPickOrderId.toString());
  510. params.append("printerId", request.printerId.toString());
  511. if (request.printQty !== null && request.printQty !== undefined) {
  512. params.append("printQty", request.printQty.toString());
  513. }
  514. params.append("numOfCarton", request.numOfCarton.toString());
  515. params.append("isDraft", request.isDraft.toString());
  516. try {
  517. const response = await serverFetch(`${BASE_API_URL}/doPickOrder/workbench/print-DN?${params.toString()}`, {
  518. method: "GET",
  519. });
  520. if (response.ok) {
  521. return { success: true, message: "Print job sent successfully (workbench DN)" } as PrintDeliveryNoteResponse;
  522. }
  523. const errorText = await response.text();
  524. console.error("Workbench print DN error:", errorText);
  525. return {
  526. success: false,
  527. message: "No workbench data found for this ticket.",
  528. } as PrintDeliveryNoteResponse;
  529. } catch (error) {
  530. console.error("Error in printDNWorkbench:", error);
  531. return {
  532. success: false,
  533. message: "No workbench data found for this ticket.",
  534. } as PrintDeliveryNoteResponse;
  535. }
  536. }
  537. export async function printDNLabelsWorkbench(request: PrintWorkbenchDNLabelsRequest){
  538. const params = new URLSearchParams();
  539. params.append("doPickOrderId", request.deliveryOrderPickOrderId.toString());
  540. params.append("printerId", request.printerId.toString());
  541. if (request.printQty !== null && request.printQty !== undefined) {
  542. params.append("printQty", request.printQty.toString());
  543. }
  544. params.append("numOfCarton", request.numOfCarton.toString());
  545. if (request.blankCartonNumber) {
  546. params.append("blankCartonNumber", "true");
  547. }
  548. await serverFetchWithNoContent(`${BASE_API_URL}/doPickOrder/workbench/print-DNLabels?${params.toString()}`,{
  549. method: "GET"
  550. });
  551. return { success: true, message: "Print job sent successfully (workbench labels)"} as PrintDeliveryNoteResponse
  552. }
  553. export async function printDNLabelsReprintWorkbench(request: PrintWorkbenchDNLabelsReprintRequest){
  554. const params = new URLSearchParams();
  555. params.append("doPickOrderId", request.deliveryOrderPickOrderId.toString());
  556. params.append("printerId", request.printerId.toString());
  557. if (request.printQty !== null && request.printQty !== undefined) {
  558. params.append("printQty", request.printQty.toString());
  559. }
  560. params.append("fromCarton", request.fromCarton.toString());
  561. params.append("toCarton", request.toCarton.toString());
  562. params.append("totalCartonsOnShipment", request.totalCartonsOnShipment.toString());
  563. await serverFetchWithNoContent(`${BASE_API_URL}/doPickOrder/workbench/print-DNLabels-reprint?${params.toString()}`,{
  564. method: "GET"
  565. });
  566. return { success: true, message: "Print job sent successfully (workbench reprint labels)"} as PrintDeliveryNoteResponse
  567. }
  568. export interface Check4FTruckBatchResponse {
  569. hasProblem: boolean;
  570. problems: ProblemDoDto[];
  571. }
  572. export interface ProblemDoDto {
  573. deliveryOrderId: number;
  574. deliveryOrderCode: string;
  575. targetDate: string;
  576. availableTrucks: TruckInfoDto[];
  577. }
  578. export interface TruckInfoDto {
  579. id: number;
  580. truckLanceCode: string;
  581. departureTime: string;
  582. storeId: string;
  583. shopCode: string;
  584. shopName: string;
  585. }
  586. export const check4FTrucksBatch = cache(async (doIds: number[]) => {
  587. return await serverFetchJson<Check4FTruckBatchResponse>(`${BASE_API_URL}/do/check-4f-trucks-batch`, {
  588. method: "POST",
  589. body: JSON.stringify(doIds),
  590. headers: { "Content-Type": "application/json" },
  591. });
  592. });
  593. export async function fetchAllDoSearch(
  594. code: string,
  595. shopName: string,
  596. status: string,
  597. estArrStartDate: string,
  598. truckLanceCode?: string,
  599. floor?: string | null,
  600. isExtra?: boolean | null,
  601. ): Promise<DoSearchAll[]> {
  602. // 使用一个很大的 pageSize 来获取所有匹配的记录
  603. const requestBody: any = {
  604. code: code || null,
  605. shopName: shopName || null,
  606. status: status || null,
  607. estimatedArrivalDate: estArrStartDate || null,
  608. truckLanceCode: truckLanceCode || null,
  609. pageNum: 1,
  610. pageSize: 10000, // 使用一个很大的值来获取所有记录
  611. floor: floor && floor !== "All" ? floor : null,
  612. ...(isExtra !== undefined && isExtra !== null ? { isExtra } : {}),
  613. };
  614. if (estArrStartDate) {
  615. requestBody.estimatedArrivalDate = estArrStartDate;
  616. } else {
  617. requestBody.estimatedArrivalDate = null;
  618. }
  619. const data = await serverFetchJson<DoSearchLiteResponse>(
  620. `${BASE_API_URL}/do/search-do-lite-v2`,
  621. {
  622. method: "POST",
  623. headers: { "Content-Type": "application/json" },
  624. body: JSON.stringify(requestBody),
  625. },
  626. );
  627. return data.records;
  628. }
  629. export async function submitDoReplenishment(
  630. lines: SubmitDoReplenishmentLineRequest[],
  631. ): Promise<DoReplenishmentRecord[]> {
  632. return serverFetchJson<DoReplenishmentRecord[]>(`${BASE_API_URL}/do/replenishment`, {
  633. method: "POST",
  634. headers: { "Content-Type": "application/json" },
  635. body: JSON.stringify({ lines }),
  636. });
  637. }
  638. export async function fetchDoReplenishmentList(params: {
  639. deliveryDate?: string;
  640. status?: string;
  641. }): Promise<DoReplenishmentRecord[]> {
  642. const query = convertObjToURLSearchParams({
  643. deliveryDate: params.deliveryDate || undefined,
  644. status: params.status && params.status !== "all" ? params.status : undefined,
  645. });
  646. const url = query
  647. ? `${BASE_API_URL}/do/replenishment?${query}`
  648. : `${BASE_API_URL}/do/replenishment`;
  649. return serverFetchJson<DoReplenishmentRecord[]>(url, {
  650. method: "GET",
  651. headers: { "Content-Type": "application/json" },
  652. });
  653. }
  654. export async function fetchDoReplenishmentForBatchRelease(params: {
  655. truckLaneCode?: string;
  656. shopName?: string;
  657. }): Promise<DoReplenishmentRecord[]> {
  658. const query = convertObjToURLSearchParams({
  659. truckLaneCode: params.truckLaneCode?.trim() || undefined,
  660. shopName: params.shopName?.trim() || undefined,
  661. });
  662. return serverFetchJson<DoReplenishmentRecord[]>(
  663. `${BASE_API_URL}/do/replenishment/for-batch-release?${query}`,
  664. {
  665. method: "GET",
  666. headers: { "Content-Type": "application/json" },
  667. },
  668. );
  669. }