feat: Enhance inventory and outbound pages with category mapping and user information

- Implemented user mapping to display user names instead of IDs in the inventory and receiving pages.
- Added category mapping for materials and units in the outbound page, improving data representation.
- Updated API calls to fetch user and category data, ensuring accurate and user-friendly displays.
- These enhancements aim to improve the overall user experience by providing clearer information and better data management across multiple company implementations.
This commit is contained in:
kjs
2026-04-12 19:34:45 +09:00
parent 3a63cafea1
commit 31bdbe1331
21 changed files with 679 additions and 119 deletions
@@ -140,31 +140,47 @@ export default function InventoryStatusPage() {
Record<string, { code: string; label: string }[]>
>({});
// 카테고리 로드
// 사용자 맵 (writer → 이름)
const [userMap, setUserMap] = useState<Record<string, string>>({});
// 카테고리 + 사용자 로드
useEffect(() => {
const load = async () => {
const optMap: Record<string, { code: string; label: string }[]> = {};
const flatten = (vals: any[]): { code: string; label: string }[] => {
const result: { code: string; label: string }[] = [];
for (const v of vals) {
result.push({ code: v.valueCode, label: v.valueLabel });
result.push({ code: v.valueCode || v.value_code || v.code, label: v.valueLabel || v.value_label || v.label });
if (v.children?.length) result.push(...flatten(v.children));
}
return result;
};
for (const col of ["status", "unit"]) {
// inventory_stock 카테고리
for (const col of ["status"]) {
try {
const res = await apiClient.get(
`/table-categories/${STOCK_TABLE}/${col}/values`
);
const res = await apiClient.get(`/table-categories/${STOCK_TABLE}/${col}/values`);
if (res.data?.success) optMap[col] = flatten(res.data.data || []);
} catch {
/* skip */
}
} catch { /* skip */ }
}
// item_info 단위 카테고리
try {
const res = await apiClient.get("/table-categories/item_info/unit/values");
if (res.data?.success) optMap["item_unit"] = flatten(res.data.data || []);
} catch { /* skip */ }
setCategoryOptions(optMap);
};
load();
// 사용자 목록 로드
apiClient.get("/admin/users").then((res) => {
const users = res.data?.data || res.data || [];
const map: Record<string, string> = {};
for (const u of users) {
const id = u.user_id || u.id;
const name = u.user_name || u.name || id;
if (id) map[id] = name;
}
setUserMap(map);
}).catch(() => {});
}, []);
// 재고 목록 조회
@@ -193,10 +209,12 @@ export default function InventoryStatusPage() {
};
const data = raw.map((r: any) => {
const itemInfo = itemMap.get(r.item_code) as any;
const rawUnit = itemInfo?.unit || r.unit || "";
return {
...r,
item_name: itemInfo?.name || "",
unit: itemInfo?.unit || resolve("unit", r.unit),
unit: resolve("item_unit", rawUnit) || rawUnit,
warehouse_code: whMap.get(r.warehouse_code) || r.warehouse_code || "",
warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
status: resolve("status", r.status),
_isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
@@ -613,7 +631,7 @@ export default function InventoryStatusPage() {
<TableCell className="truncate max-w-[150px]">
{h.remark || h.reason || ""}
</TableCell>
<TableCell>{h.writer || h.created_by || ""}</TableCell>
<TableCell>{userMap[h.writer] || userMap[h.created_by] || h.writer || h.created_by || ""}</TableCell>
</TableRow>
))}
</TableBody>