FPSMS-frontend
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

319 line
8.3 KiB

  1. "use server";
  2. import { cache } from 'react';
  3. import { Pageable, serverFetchJson } from "@/app/utils/fetchUtil";
  4. import { JoStatus, Machine, Operator } from ".";
  5. import { BASE_API_URL } from "@/config/api";
  6. import { revalidateTag } from "next/cache";
  7. import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";
  8. export interface SaveJo {
  9. bomId: number;
  10. planStart: string;
  11. planEnd: string;
  12. reqQty: number;
  13. type: string;
  14. }
  15. export interface SaveJoResponse {
  16. id: number;
  17. }
  18. export interface SearchJoResultRequest extends Pageable {
  19. code: string;
  20. name: string;
  21. }
  22. export interface SearchJoResultResponse {
  23. records: SearchJoResult[];
  24. total: number;
  25. }
  26. export interface SearchJoResult {
  27. id: number;
  28. code: string;
  29. name: string;
  30. reqQty: number;
  31. uom: string;
  32. status: JoStatus;
  33. }
  34. // For Jo Button Actions
  35. export interface CommonActionJoRequest {
  36. id: number;
  37. }
  38. export interface CommonActionJoResponse {
  39. id: number;
  40. entity: { status: JoStatus }
  41. }
  42. // For Jo Process
  43. export interface IsOperatorExistResponse<T> {
  44. id: number | null;
  45. name: string;
  46. code: string;
  47. type?: string;
  48. message: string | null;
  49. errorPosition: string | keyof T;
  50. entity: T;
  51. }
  52. export interface isCorrectMachineUsedResponse<T> {
  53. id: number | null;
  54. name: string;
  55. code: string;
  56. type?: string;
  57. message: string | null;
  58. errorPosition: string | keyof T;
  59. entity: T;
  60. }
  61. export interface JobOrderDetail {
  62. id: number;
  63. code: string;
  64. name: string;
  65. reqQty: number;
  66. uom: string;
  67. pickLines: any[];
  68. status: string;
  69. }
  70. export interface UnassignedJobOrderPickOrder {
  71. pickOrderId: number;
  72. pickOrderCode: string;
  73. pickOrderConsoCode: string;
  74. pickOrderTargetDate: string;
  75. pickOrderStatus: string;
  76. jobOrderId: number;
  77. jobOrderCode: string;
  78. jobOrderName: string;
  79. reqQty: number;
  80. uom: string;
  81. planStart: string;
  82. planEnd: string;
  83. }
  84. export interface AssignJobOrderResponse {
  85. id: number | null;
  86. code: string | null;
  87. name: string | null;
  88. type: string | null;
  89. message: string | null;
  90. errorPosition: string | null;
  91. }
  92. export const recordSecondScanIssue = cache(async (
  93. pickOrderId: number,
  94. itemId: number,
  95. data: {
  96. qty: number;
  97. isMissing: boolean;
  98. isBad: boolean;
  99. reason: string;
  100. createdBy: number;
  101. }
  102. ) => {
  103. return serverFetchJson<any>(
  104. `${BASE_API_URL}/jo/second-scan-issue/${pickOrderId}/${itemId}`,
  105. {
  106. method: "POST",
  107. headers: { "Content-Type": "application/json" },
  108. body: JSON.stringify(data),
  109. next: { tags: ["jo-second-scan"] },
  110. },
  111. );
  112. });
  113. export const updateSecondQrScanStatus = cache(async (pickOrderId: number, itemId: number) => {
  114. return serverFetchJson<any>(
  115. `${BASE_API_URL}/jo/second-scan-qr/${pickOrderId}/${itemId}`,
  116. {
  117. method: "POST",
  118. next: { tags: ["jo-second-scan"] },
  119. },
  120. );
  121. });
  122. export const submitSecondScanQuantity = cache(async (
  123. pickOrderId: number,
  124. itemId: number,
  125. data: { qty: number; isMissing?: boolean; isBad?: boolean; reason?: string }
  126. ) => {
  127. return serverFetchJson<any>(
  128. `${BASE_API_URL}/jo/second-scan-submit/${pickOrderId}/${itemId}`,
  129. {
  130. method: "POST",
  131. headers: { "Content-Type": "application/json" },
  132. body: JSON.stringify(data),
  133. next: { tags: ["jo-second-scan"] },
  134. },
  135. );
  136. });
  137. // 获取未分配的 Job Order pick orders
  138. export const fetchUnassignedJobOrderPickOrders = cache(async () => {
  139. return serverFetchJson<UnassignedJobOrderPickOrder[]>(
  140. `${BASE_API_URL}/jo/unassigned-job-order-pick-orders`,
  141. {
  142. method: "GET",
  143. next: { tags: ["jo-unassigned"] },
  144. },
  145. );
  146. });
  147. // 分配 Job Order pick order 给用户
  148. export const assignJobOrderPickOrder = async (pickOrderId: number, userId: number) => {
  149. return serverFetchJson<AssignJobOrderResponse>(
  150. `${BASE_API_URL}/jo/assign-job-order-pick-order/${pickOrderId}/${userId}`,
  151. {
  152. method: "POST",
  153. headers: { "Content-Type": "application/json" },
  154. }
  155. );
  156. };
  157. // 获取 Job Order 分层数据
  158. export const fetchJobOrderLotsHierarchical = cache(async (userId: number) => {
  159. return serverFetchJson<any>(
  160. `${BASE_API_URL}/jo/all-lots-hierarchical/${userId}`,
  161. {
  162. method: "GET",
  163. next: { tags: ["jo-hierarchical"] },
  164. },
  165. );
  166. });
  167. export const fetchCompletedJobOrderPickOrders = cache(async (userId: number) => {
  168. return serverFetchJson<any>(
  169. `${BASE_API_URL}/jo/completed-job-order-pick-orders${userId}`,
  170. {
  171. method: "GET",
  172. next: { tags: ["jo-completed"] },
  173. },
  174. );
  175. });
  176. // 获取已完成的 Job Order pick orders
  177. export const fetchCompletedJobOrderPickOrdersrecords = cache(async (userId: number) => {
  178. return serverFetchJson<any>(
  179. `${BASE_API_URL}/jo/completed-job-order-pick-orders-only/${userId}`,
  180. {
  181. method: "GET",
  182. next: { tags: ["jo-completed"] },
  183. },
  184. );
  185. });
  186. // 获取已完成的 Job Order pick order records
  187. export const fetchCompletedJobOrderPickOrderRecords = cache(async (userId: number) => {
  188. return serverFetchJson<any[]>(
  189. `${BASE_API_URL}/jo/completed-job-order-pick-order-records/${userId}`,
  190. {
  191. method: "GET",
  192. next: { tags: ["jo-records"] },
  193. },
  194. );
  195. });
  196. export const fetchJobOrderDetailByCode = cache(async (code: string) => {
  197. return serverFetchJson<JobOrderDetail>(
  198. `${BASE_API_URL}/jo/detailByCode/${code}`,
  199. {
  200. method: "GET",
  201. next: { tags: ["jo"] },
  202. },
  203. );
  204. });
  205. export const isOperatorExist = async (username: string) => {
  206. const isExist = await serverFetchJson<IsOperatorExistResponse<Operator>>(
  207. `${BASE_API_URL}/jop/isOperatorExist`,
  208. {
  209. method: "POST",
  210. body: JSON.stringify({ username }),
  211. headers: { "Content-Type": "application/json" },
  212. },
  213. );
  214. revalidateTag("po");
  215. return isExist;
  216. };
  217. export const isCorrectMachineUsed = async (machineCode: string) => {
  218. const isExist = await serverFetchJson<isCorrectMachineUsedResponse<Machine>>(
  219. `${BASE_API_URL}/jop/isCorrectMachineUsed`,
  220. {
  221. method: "POST",
  222. body: JSON.stringify({ machineCode }),
  223. headers: { "Content-Type": "application/json" },
  224. },
  225. );
  226. revalidateTag("po");
  227. return isExist;
  228. };
  229. export const fetchJos = cache(async (data?: SearchJoResultRequest) => {
  230. const queryStr = convertObjToURLSearchParams(data)
  231. const response = serverFetchJson<SearchJoResultResponse>(
  232. `${BASE_API_URL}/jo/getRecordByPage?${queryStr}`,
  233. {
  234. method: "GET",
  235. headers: { "Content-Type": "application/json" },
  236. next: {
  237. tags: ["jos"]
  238. }
  239. }
  240. )
  241. return response
  242. })
  243. export const releaseJo = cache(async (data: CommonActionJoRequest) => {
  244. const response = serverFetchJson<CommonActionJoResponse>(`${BASE_API_URL}/jo/release`,
  245. {
  246. method: "POST",
  247. body: JSON.stringify(data),
  248. headers: { "Content-Type": "application/json" },
  249. })
  250. // Invalidate the cache after releasing
  251. revalidateTag("jo");
  252. return response;
  253. })
  254. export const startJo = cache(async (data: CommonActionJoRequest) => {
  255. const response = serverFetchJson<CommonActionJoResponse>(`${BASE_API_URL}/jo/start`,
  256. {
  257. method: "POST",
  258. body: JSON.stringify(data),
  259. headers: { "Content-Type": "application/json" },
  260. })
  261. // Invalidate the cache after starting
  262. revalidateTag("jo");
  263. return response;
  264. })
  265. export const manualCreateJo = cache(async (data: SaveJo) => {
  266. return serverFetchJson<SaveJoResponse>(`${BASE_API_URL}/jo/manualCreate`, {
  267. method: "POST",
  268. body: JSON.stringify(data),
  269. headers: { "Content-Type": "application/json" }
  270. })
  271. })
  272. export const fetchCompletedJobOrderPickOrdersWithCompletedSecondScan = cache(async (userId: number) => {
  273. return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-orders-with-completed-second-scan/${userId}`, {
  274. method: "GET",
  275. headers: { "Content-Type": "application/json" }
  276. })
  277. })
  278. export const fetchCompletedJobOrderPickOrderLotDetails = cache(async (pickOrderId: number) => {
  279. return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-order-lot-details/${pickOrderId}`, {
  280. method: "GET",
  281. headers: { "Content-Type": "application/json" }
  282. })
  283. })
  284. export const fetchCompletedJobOrderPickOrderLotDetailsForCompletedPick = cache(async (pickOrderId: number) => {
  285. return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-order-lot-details-completed-pick/${pickOrderId}`, {
  286. method: "GET",
  287. headers: { "Content-Type": "application/json" }
  288. })
  289. })