|
- "use server";
- import { BASE_API_URL } from "@/config/api";
- // import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
- import { revalidateTag } from "next/cache";
- import { cache } from "react";
- import { serverFetch, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
- import { QcItemResult } from "../settings/qcItem";
- import { RecordsRes } from "../utils";
- import { DoResult } from ".";
- import { GridRowId, GridRowSelectionModel } from "@mui/x-data-grid";
- import { GET } from "../auth/[...nextauth]/route";
- import { stringify } from "querystring";
- import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";
- export interface CreateConsoDoInput {
- ids: GridRowSelectionModel;
- }
- export interface DoDetail {
- id: number;
- code: string;
- supplierCode: string;
- shopCode: string;
- shopName: string;
- currencyCode: string;
- orderDate: string;
- estimatedArrivalDate: string;
- completeDate: string;
- status: string;
- deliveryOrderLines: DoDetailLine[];
- }
-
- export interface DoDetailLine {
- id: number;
- itemNo: string;
- qty: number;
- price: number;
- status: string;
- itemName?: string;
- uomCode?: string;
- uom?: string;
- shortUom?: string;
- }
-
- export interface DoSearchAll {
- id: number;
- code: string;
- status: string;
- estimatedArrivalDate: number[];
- orderDate: number[];
- supplierName: string;
- shopName: string;
- shopAddress?: string;
-
- }
- export interface DoSearchLiteResponse {
- records: DoSearchAll[];
- total: number;
- }
- export interface ReleaseDoRequest {
- id: number;
- }
-
- export interface ReleaseDoResponse {
- id: number;
- entity: { status: string }
- }
-
-
- export interface AssignByStoreRequest {
- storeId: string; // "2/F" or "4/F"
- assignTo: number;
- }
-
- export interface AssignByStoreResponse {
- id: number;
- code: string;
- name: string;
- type: string;
- message: string;
- errorPosition: string;
- entity: any;
- }
-
- export interface PrintDeliveryNoteRequest{
- doPickOrderId: number;
- printerId: number;
- printQty: number;
- numOfCarton: number;
- isDraft: boolean;
- }
-
- export interface PrintDeliveryNoteResponse{
- success: boolean;
- message?: string
- }
-
- export interface PrintDNLabelsRequest{
- doPickOrderId: number;
- printerId: number;
- printQty: number;
- numOfCarton: number;
- }
-
- export interface PrintDNLabelsRespone{
- success: boolean;
- message?: string
- }
- export interface BatchReleaseRequest {
- ids: number[];
- }
- export interface BatchReleaseResponse {
- success: boolean;
- message?: string
- }
-
- export interface getTicketReleaseTable {
- id: number;
- storeId: string | null;
- ticketNo: string | null;
- pickOrderId: number | null;
- doOrderId: number | null;
- pickOrderCode: string | null;
- deliveryOrderCode: string | null;
- loadingSequence: number | null;
- ticketStatus: string | null;
- truckId: number | null;
- truckDepartureTime: string | null;
- shopId: number | null;
- handledBy: number | null;
- ticketReleaseTime: string | null;
- ticketCompleteDateTime: string | null;
- truckLanceCode: string | null;
- shopCode: string | null;
- shopName: string | null;
- requiredDeliveryDate: string | null;
- handlerName: string | null;
- numberOfFGItems: number;
- /** 進行中 do_pick_order 為 true,才可呼叫 force-complete / revert-assignment(id 為 do_pick_order 主鍵) */
- isActiveDoPickOrder?: boolean;
- }
-
- export interface TruckScheduleDashboardItem {
- storeId: string | null;
- truckId: number | null;
- truckLanceCode: string | null;
- truckDepartureTime: string | number[] | null;
- numberOfShopsToServe: number;
- numberOfPickTickets: number;
- totalItemsToPick: number;
- numberOfTicketsReleased: number;
- firstTicketStartTime: string | number[] | null;
- numberOfTicketsCompleted: number;
- lastTicketEndTime: string | number[] | null;
- pickTimeTakenMinutes: number | null;
- }
- export interface SearchDeliveryOrderInfoRequest {
- code: string;
- shopName: string;
- status: string;
- orderStartDate: string;
- orderEndDate: string;
- estArrStartDate: string;
- estArrEndDate: string;
- pageSize: number;
- pageNum: number;
- }
- export interface SearchDeliveryOrderInfoResponse {
- records: DeliveryOrderInfo[];
- total: number;
- }
- export interface DeliveryOrderInfo {
- id: number;
- code: string;
- shopName: string;
- supplierName: string; // 改为必需字段
- status: string;
- orderDate: string;
-
- estimatedArrivalDate: string;
- deliveryOrderLines: DoDetailLine[];
- }
- export const fetchDoRecordByPage = cache(async (data?: SearchDeliveryOrderInfoRequest) => {
- const queryStr = convertObjToURLSearchParams(data)
- console.log("queryStr", queryStr)
- const response = serverFetchJson<SearchDeliveryOrderInfoResponse>(
- `${BASE_API_URL}/jo/getRecordByPage?${queryStr}`,
- {
- method: "GET",
- headers: { "Content-Type": "application/json" },
- next: {
- tags: ["jos"]
- }
- }
- )
-
- return response
- })
- export const fetchTicketReleaseTable = cache(async (startDate: string, endDate: string)=> {
- return await serverFetchJson<getTicketReleaseTable[]>(
- `${BASE_API_URL}/doPickOrder/ticket-release-table/${startDate}&${endDate}`,
- {
- method: "GET",
- }
- );
- });
-
- export const fetchTruckScheduleDashboard = cache(async (date?: string) => {
- const url = date
- ? `${BASE_API_URL}/doPickOrder/truck-schedule-dashboard?date=${date}`
- : `${BASE_API_URL}/doPickOrder/truck-schedule-dashboard`;
- return await serverFetchJson<TruckScheduleDashboardItem[]>(
- url,
- {
- method: "GET",
- }
- );
- });
- export const startBatchReleaseAsyncSingle = cache(async (data: { doId: number; userId: number }) => {
- const { doId, userId } = data;
- return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
- `${BASE_API_URL}/doPickOrder/batch-release/async-single?userId=${userId}`,
- {
- method: "POST",
- body: JSON.stringify(doId),
- headers: { "Content-Type": "application/json" },
- }
- );
- });
- export const startBatchReleaseAsync = cache(async (data: { ids: number[]; userId: number }) => {
- const { ids, userId } = data;
- return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
- `${BASE_API_URL}/doPickOrder/batch-release/async?userId=${userId}`,
- {
- method: "POST",
- body: JSON.stringify(ids),
- headers: { "Content-Type": "application/json" },
- }
- );
- });
-
- export const getBatchReleaseProgress = cache(async (jobId: string) => {
- return await serverFetchJson<{ id: number|null; code: string; entity?: any }>(
- `${BASE_API_URL}/doPickOrder/batch-release/progress/${jobId}`,
- { method: "GET" }
- );
- });
- export const assignPickOrderByStore = cache(async (data: AssignByStoreRequest) => {
- return await serverFetchJson<AssignByStoreResponse>(`${BASE_API_URL}/doPickOrder/assign-by-store`,
- {
- method: "POST",
- body: JSON.stringify(data),
- headers: { "Content-Type": "application/json" },
- })
- })
-
- export const releaseAssignedPickOrderByStore = cache(async (data: AssignByStoreRequest) => {
- return await serverFetchJson<AssignByStoreResponse>(`${BASE_API_URL}/doPickOrder/release-assigned-by-store`,
- {
- method: "POST",
- body: JSON.stringify(data),
- headers: { "Content-Type": "application/json" },
- })
- })
-
- export async function releaseDo(input: ReleaseDoRequest) {
- const response = await serverFetchJson<ReleaseDoResponse>(`${BASE_API_URL}/do/release`, {
- method: 'POST',
- body: JSON.stringify(input),
- headers: {
- 'Content-Type': 'application/json',
- },
- });
- revalidateTag('do');
- return response;
- }
- export const preloadDo = () => {
- fetchDoList();
- };
-
- export const fetchDoList = cache(async () => {
- return serverFetchJson<DoResult[]>(`${BASE_API_URL}/do/list`, {
- next: { tags: ["doList"] },
- });
- });
-
- export const fetchDoDetail = cache(async (id: number) => {
- return serverFetchJson<DoDetail>(`${BASE_API_URL}/do/detail/${id}`, {
- method: "GET",
- headers: { "Content-Type": "application/json" },
- next: {
- tags: ["doDetail"]
- }
- });
- });
-
- export async function fetchDoSearch(
- code: string,
- shopName: string,
- status: string,
- orderStartDate: string,
- orderEndDate: string,
- estArrStartDate: string,
- estArrEndDate: string,
- pageNum?: number,
- pageSize?: number,
- truckLanceCode?: string
- ): Promise<DoSearchLiteResponse> {
- // 构建请求体
- const requestBody: any = {
- code: code || null,
- shopName: shopName || null,
- status: status || null,
- estimatedArrivalDate: estArrStartDate || null, // 使用单个日期字段
- truckLanceCode: truckLanceCode || null,
- pageNum: pageNum || 1,
- pageSize: pageSize || 10,
- };
-
- // 如果日期不为空,转换为 LocalDateTime 格式
- if (estArrStartDate) {
- requestBody.estimatedArrivalDate = estArrStartDate; // 格式: "2026-01-19T00:00:00"
- } else {
- requestBody.estimatedArrivalDate = null;
- }
-
- const url = `${BASE_API_URL}/do/search-do-lite`;
-
- const data = await serverFetchJson<DoSearchLiteResponse>(url, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify(requestBody),
- });
-
- return data;
- }
- export async function fetchDoSearchList(
- code: string,
- shopName: string,
- status: string,
- orderStartDate: string,
- orderEndDate: string,
- etaFrom: string,
- etaTo: string,
- page = 0,
- size = 500
- ): Promise<DoSearchAll[]> {
- const params = new URLSearchParams();
-
- if (code) params.append("code", code);
- if (shopName) params.append("shopName", shopName);
- if (status) params.append("status", status);
- if (orderStartDate) params.append("orderFrom", orderStartDate);
- if (orderEndDate) params.append("orderTo", orderEndDate);
- if (etaFrom) params.append("etaFrom", etaFrom);
- if (etaTo) params.append("etaTo", etaTo);
-
- params.append("page", String(page));
- params.append("size", String(size));
-
- const res = await fetch(`/api/delivery-order/search-do-list?${params.toString()}`);
- const pageData = await res.json(); // Spring Page 结构
- return pageData.content; // 前端继续沿用你原来的 client-side 分页逻辑
- }
- export async function printDN(request: PrintDeliveryNoteRequest){
- const params = new URLSearchParams();
- params.append('doPickOrderId', request.doPickOrderId.toString());
- params.append('printerId', request.printerId.toString());
- if (request.printQty !== null && request.printQty !== undefined) {
- params.append('printQty', request.printQty.toString());
- }
- params.append('numOfCarton', request.numOfCarton.toString());
- params.append('isDraft', request.isDraft.toString());
-
- try {
- const response = await serverFetch(`${BASE_API_URL}/do/print-DN?${params.toString()}`, {
- method: "GET",
- });
-
- if (response.ok) {
- return { success: true, message: "Print job sent successfully (DN)" } as PrintDeliveryNoteResponse;
- }
-
- const errorText = await response.text();
- console.error("Print DN error:", errorText);
- return {
- success: false,
- message: "No data found for this pick order."
- } as PrintDeliveryNoteResponse;
-
- } catch (error) {
- console.error("Error in printDN:", error);
- return {
- success: false,
- message: "No data found for this pick order."
- } as PrintDeliveryNoteResponse;
- }
- }
-
- export async function printDNLabels(request: PrintDNLabelsRequest){
- const params = new URLSearchParams();
- params.append('doPickOrderId', request.doPickOrderId.toString());
- params.append('printerId', request.printerId.toString());
- if (request.printQty !== null && request.printQty !== undefined) {
- params.append('printQty', request.printQty.toString());
- }
- params.append('numOfCarton', request.numOfCarton.toString());
-
- const response = await serverFetchWithNoContent(`${BASE_API_URL}/do/print-DNLabels?${params.toString()}`,{
- method: "GET"
- });
-
- return { success: true, message: "Print job sent successfully (labels)"} as PrintDeliveryNoteResponse
- }
- export interface Check4FTruckBatchResponse {
- hasProblem: boolean;
- problems: ProblemDoDto[];
- }
- export interface ProblemDoDto {
- deliveryOrderId: number;
- deliveryOrderCode: string;
- targetDate: string;
- availableTrucks: TruckInfoDto[];
- }
- export interface TruckInfoDto {
- id: number;
- truckLanceCode: string;
- departureTime: string;
- storeId: string;
- shopCode: string;
- shopName: string;
- }
- export const check4FTrucksBatch = cache(async (doIds: number[]) => {
- return await serverFetchJson<Check4FTruckBatchResponse>(`${BASE_API_URL}/do/check-4f-trucks-batch`, {
- method: "POST",
- body: JSON.stringify(doIds),
- headers: { "Content-Type": "application/json" },
- });
- });
-
- export async function fetchAllDoSearch(
- code: string,
- shopName: string,
- status: string,
- estArrStartDate: string,
- truckLanceCode?: string // 添加这个参数
- ): Promise<DoSearchAll[]> {
- // 使用一个很大的 pageSize 来获取所有匹配的记录
- const requestBody: any = {
- code: code || null,
- shopName: shopName || null,
- status: status || null,
- estimatedArrivalDate: estArrStartDate || null,
- truckLanceCode: truckLanceCode || null, // 添加这个字段
- pageNum: 1,
- pageSize: 10000, // 使用一个很大的值来获取所有记录
- };
-
- if (estArrStartDate) {
- requestBody.estimatedArrivalDate = estArrStartDate;
- } else {
- requestBody.estimatedArrivalDate = null;
- }
-
- const url = `${BASE_API_URL}/do/search-do-lite`;
-
- const data = await serverFetchJson<DoSearchLiteResponse>(url, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify(requestBody),
- });
-
- return data.records;
- }
|