From d4eea885bad62c7f1f9049ebcffb5f7558691f9e Mon Sep 17 00:00:00 2001 From: Aloento <11802769+Aloento@users.noreply.github.com> Date: Thu, 15 Feb 2024 19:08:01 +0100 Subject: [PATCH] The most significant changes involve the restructuring of methods in the `AdminHub` and `ShopHub` classes, and the modification of components and functions in `Drawer.tsx`, `index.tsx`, `Detail.tsx`, and `List.tsx`. The `OrderGetDetail` method in `AdminHub` class has been divided into two separate methods, `OrderGetItems` and `OrderGetCmts`, to retrieve order items and comments respectively. The `OrderGetItems` and `OrderGetCmts` methods in `ShopHub` class have been updated to change the order of the `Where` clauses. In `Drawer.tsx`, the `AdminOrderList` component has been imported and used conditionally based on the `Admin` prop in `OrderDetailDrawer` function. The `OrderDetail` function in `index.tsx` has been updated to change the index used to set the `curr` variable based on the `Admin` prop. The `AdminOrderDetail` function in `Detail.tsx` has been updated to remove the `Field` component wrapping the `AdminOrderList` component. The `AdminOrderList` function in `List.tsx` has been updated to wrap the `DelegateDataGrid` component with a `Field` component. The `AdminOrderGet` class in `Get.ts` has been updated to remove the `Detail` method. The `OrderGet` class in `Get.ts` has been updated to add an optional `admin` parameter to the `useItems` and `useCmts` methods. This parameter is used to determine whether to use `AdminNet` or `this` for the `useTimeCache` method. Lastly, the `SignalR` class in `SignalR.ts` has been updated to change the `INet` type to be a member of the `SignalR` namespace. All methods in the `SignalR` class that used `INet` have been updated to use `SignalR.INet` instead. The `GetVersionCache`, `GetTimeCache`, `useTimeCache`, `UpdateCache` methods in `SignalR` class have been updated to use `SignalR.INet` instead of `INet`. --- SoarCraft.AwaiShop/AdminHub/Order/Get.cs | 22 ++--- SoarCraft.AwaiShop/Hub/Order/Get.cs | 6 +- src/Components/Order/Drawer.tsx | 19 ++-- src/Components/Order/index.tsx | 2 +- src/Pages/Admin/Order/Detail.tsx | 6 +- src/Pages/Admin/Order/List.tsx | 6 +- src/ShopNet/Admin/Order/Get.ts | 105 ----------------------- src/ShopNet/Order/Get.ts | 70 ++++++++++----- src/ShopNet/SignalR.ts | 27 +++--- 9 files changed, 98 insertions(+), 165 deletions(-) diff --git a/SoarCraft.AwaiShop/AdminHub/Order/Get.cs b/SoarCraft.AwaiShop/AdminHub/Order/Get.cs index 397df41..f2952b0 100644 --- a/SoarCraft.AwaiShop/AdminHub/Order/Get.cs +++ b/SoarCraft.AwaiShop/AdminHub/Order/Get.cs @@ -35,11 +35,11 @@ await this.Db.Orders * * @author Aloento * @since 1.0.0 - * @version 1.0.0 + * @version 1.1.0 * */ - public async Task OrderGetDetail(uint orderId) { - var items = await this.Db.OrderCombos + public async Task OrderGetItems(uint orderId) => + await this.Db.OrderCombos .Where(x => x.OrderId == orderId) .Select(x => new { x.Quantity, @@ -47,14 +47,16 @@ public async Task OrderGetDetail(uint orderId) { }) .ToArrayAsync(); - var cmts = await this.Db.Comments + /** + * + * @author Aloento + * @since 1.0.0 + * @version 1.1.0 + * + */ + public Task OrderGetCmts(uint orderId) => + this.Db.Comments .Where(x => x.OrderId == orderId) .Select(x => x.CommentId) .ToArrayAsync(); - - return new { - Items = items, - Comments = cmts - }; - } } diff --git a/SoarCraft.AwaiShop/Hub/Order/Get.cs b/SoarCraft.AwaiShop/Hub/Order/Get.cs index 2e82401..76c85d2 100644 --- a/SoarCraft.AwaiShop/Hub/Order/Get.cs +++ b/SoarCraft.AwaiShop/Hub/Order/Get.cs @@ -32,7 +32,8 @@ await this.Db.Orders [Authorize] public async Task OrderGetItems(uint orderId) => await this.Db.OrderCombos - .Where(x => x.OrderId == orderId && x.Order.UserId == this.UserId) + .Where(x => x.Order.UserId == this.UserId) + .Where(x => x.OrderId == orderId) .Select(x => new { x.Quantity, Types = x.Combo.Types.Select(t => t.TypeId).ToArray() @@ -49,7 +50,8 @@ await this.Db.OrderCombos [Authorize] public Task OrderGetCmts(uint orderId) => this.Db.Comments - .Where(x => x.OrderId == orderId && x.Order.UserId == this.UserId) + .Where(x => x.Order.UserId == this.UserId) + .Where(x => x.OrderId == orderId) .Select(x => x.CommentId) .ToArrayAsync(); } diff --git a/src/Components/Order/Drawer.tsx b/src/Components/Order/Drawer.tsx index bec7a37..f685792 100644 --- a/src/Components/Order/Drawer.tsx +++ b/src/Components/Order/Drawer.tsx @@ -7,6 +7,7 @@ import { ICartItem } from "~/Components/ShopCart"; import { MakeCoverCol } from "~/Helpers/CoverCol"; import { ColFlex } from "~/Helpers/Styles"; import { useSWR } from "~/Helpers/useSWR"; +import { AdminOrderList } from "~/Pages/Admin/Order/List"; import { Hub } from "~/ShopNet"; import { AdminHub } from "~/ShopNet/Admin"; import { SignalR } from "~/ShopNet/SignalR"; @@ -100,16 +101,22 @@ export function OrderDetailDrawer({ OrderId, Admin, ParentLog }: IOrderComp) { useMemory: true }); - const { data: cart } = Hub.Order.Get.useItems(OrderId, ParentLog); + const { data: cart } = Hub.Order.Get.useItems(OrderId, ParentLog, Admin); return (
- + - + { + Admin + ? + + : + + } diff --git a/src/Components/Order/index.tsx b/src/Components/Order/index.tsx index 946f1cb..11a1bab 100644 --- a/src/Components/Order/index.tsx +++ b/src/Components/Order/index.tsx @@ -32,7 +32,7 @@ export function OrderDetail({ OrderId, Admin, ParentLog }: IOrderComp) { const [open, { set }] = useBoolean(); const { Nav, Paths } = useRouter(); - const curr = parseInt(Paths.at(1)!); + const curr = parseInt(Paths.at(Admin ? 2 : 1)!); useEffect(() => set(curr === OrderId), [curr]); const ref = useRef(null); diff --git a/src/Pages/Admin/Order/Detail.tsx b/src/Pages/Admin/Order/Detail.tsx index 91537c4..d44f21a 100644 --- a/src/Pages/Admin/Order/Detail.tsx +++ b/src/Pages/Admin/Order/Detail.tsx @@ -1,4 +1,4 @@ -import { Button, Field, makeStyles, tokens } from "@fluentui/react-components"; +import { Button, makeStyles, tokens } from "@fluentui/react-components"; import { Drawer, DrawerBody, DrawerHeader, DrawerHeaderTitle } from "@fluentui/react-components/unstable"; import { DismissRegular, OpenRegular } from "@fluentui/react-icons"; import { useBoolean, useRequest } from "ahooks"; @@ -96,9 +96,7 @@ export function AdminOrderDetail({ OrderId }: { OrderId: number; }) { - - - + diff --git a/src/Pages/Admin/Order/List.tsx b/src/Pages/Admin/Order/List.tsx index 17f6303..31ced90 100644 --- a/src/Pages/Admin/Order/List.tsx +++ b/src/Pages/Admin/Order/List.tsx @@ -1,4 +1,4 @@ -import { DataGridCell, DataGridHeaderCell, TableColumnDefinition, createTableColumn, makeStyles } from "@fluentui/react-components"; +import { DataGridCell, DataGridHeaderCell, Field, TableColumnDefinition, createTableColumn, makeStyles } from "@fluentui/react-components"; import { DelegateDataGrid } from "~/Components/DataGrid"; import { ICartItem } from "~/Components/ShopCart"; @@ -64,6 +64,8 @@ const columns: TableColumnDefinition[] = [ */ export function AdminOrderList({ Items }: { Items?: ICartItem[] }) { return ( - + + + ) } diff --git a/src/ShopNet/Admin/Order/Get.ts b/src/ShopNet/Admin/Order/Get.ts index 80fc46f..7dfca6e 100644 --- a/src/ShopNet/Admin/Order/Get.ts +++ b/src/ShopNet/Admin/Order/Get.ts @@ -1,10 +1,6 @@ -import { IOrderComp } from "~/Components/Order"; -import { ICartItem } from "~/Components/ShopCart"; import { Logger } from "~/Helpers/Logger"; import { IAdminOrderItem } from "~/Pages/Admin/Order"; -import { IComment } from "~/Pages/History/Comment"; import { ProductData } from "~/ShopNet/Product/Data"; -import { ProductGet } from "~/ShopNet/Product/Get"; import { AdminNet } from "../AdminNet"; import { AdminUserEntity } from "../User/Entity"; import { AdminOrderEntity } from "./Entity"; @@ -90,107 +86,6 @@ export abstract class AdminOrderGet extends AdminNet { return items; } - /** - * @author Aloento - * @since 1.0.0 - * @version 0.1.1 - */ - public static async Detail(orderId: number, pLog: Logger): Promise { - this.EnsureLogin(); - const log = pLog.With(...this.Log, "Detail"); - - const meta = await this.GetTimeCache< - { - Items: { - Types: number[]; - Quantity: number; - }[], - Comments: number[]; - } - >(orderId, "OrderGetDetail", (x) => x.add(1, "m"), orderId); - - const items: ICartItem[] = []; - let index = 0; - - for (const combo of meta.Items) { - const variType: Record = {}; - let prodId = 0; - - for (const typeId of combo.Types) { - const type = await ProductData.Type(typeId); - - if (!type) { - log.warn(`[Mismatch] Type ${typeId} not found. Order : ${orderId}`); - continue; - } - - const vari = await ProductData.Variant(type.VariantId); - - if (!vari) { - log.warn(`[Mismatch] Variant ${type.VariantId} not found. Type : ${typeId}, Order : ${orderId}`); - continue; - } - - variType[vari.Name] = type.Name; - prodId = vari.ProductId; - } - - const prod = await ProductData.Product(prodId); - - if (!prod) { - log.warn(`[Mismatch] Product ${prodId} not found. Order : ${orderId}`); - continue; - } - - const [_, cover] = await ProductGet.PhotoList(prodId, log); - - if (!cover) - log.warn(`Product ${prodId} has no photo`); - - items.push({ - Id: index++, - ProdId: prodId, - Cover: cover || "", - Name: prod.Name, - Type: variType, - Quantity: combo.Quantity, - }); - } - - const comments: IComment[] = []; - - for (const cmtId of meta.Comments) { - const cmt = await AdminOrderEntity.Comment(cmtId); - - if (!cmt) { - log.warn(`[Mismatch] Comment ${cmtId} not found. Order : ${orderId}`); - continue; - } - - let name = "Client"; - - if (cmt.UserId) { - const user = await AdminUserEntity.User(cmt.UserId); - - if (user) - name = user.Name; - else - log.warn(`[Mismatch] User ${cmt.UserId} not found. Order : ${orderId}`); - } - - comments.push({ - Content: cmt.Content, - Time: cmt.CreateAt, - User: name - }); - } - - return { - ShopCart: items, - Comments: comments.sort((a, b) => a.Time.getTime() - b.Time.getTime()) - }; - } - public static Order = AdminOrderEntity.Order; public static Export = AdminOrderExport.Export; } diff --git a/src/ShopNet/Order/Get.ts b/src/ShopNet/Order/Get.ts index d7b9445..a0c26aa 100644 --- a/src/ShopNet/Order/Get.ts +++ b/src/ShopNet/Order/Get.ts @@ -1,10 +1,13 @@ import { useConst } from "@fluentui/react-hooks"; import { useAsyncEffect } from "ahooks"; import { useState } from "react"; -import { IComment } from "~/Components/Order/Comment"; -import { ICartItem } from "~/Components/ShopCart"; +import type { IComment } from "~/Components/Order/Comment"; +import type { ICartItem } from "~/Components/ShopCart"; import { Logger } from "~/Helpers/Logger"; -import { IOrderItem } from "~/Pages/History"; +import type { IOrderItem } from "~/Pages/History"; +import { AdminNet } from "../Admin/AdminNet"; +import { AdminOrderEntity } from "../Admin/Order/Entity"; +import { AdminUserEntity } from "../Admin/User/Entity"; import { ProductData } from "../Product/Data"; import { ProductGet } from "../Product/Get"; import { OrderEntity } from "./Entity"; @@ -75,13 +78,13 @@ export abstract class OrderGet extends OrderEntity { /** * @author Aloento * @since 0.5.0 - * @version 2.0.0 + * @version 2.1.0 */ - public static useItems(orderId: number, pLog: Logger) { + public static useItems(orderId: number, pLog: Logger, admin?: true) { const log = useConst(() => pLog.With(...this.Log, "Items")); const [res, setRes] = useState(); - const req = this.useTimeCache< + const req = (admin ? AdminNet : this).useTimeCache< { Types: number[]; Quantity: number; @@ -160,13 +163,13 @@ export abstract class OrderGet extends OrderEntity { /** * @author Aloento * @since 1.3.5 - * @version 0.1.0 + * @version 1.0.0 */ - public static useCmts(orderId: number, pLog: Logger) { + public static useCmts(orderId: number, pLog: Logger, admin?: true) { const log = useConst(() => pLog.With(...this.Log, "Cmts")); const [res, setRes] = useState(); - const req = this.useTimeCache( + const req = (admin ? AdminNet : this).useTimeCache( orderId, "OrderGetCmts", { @@ -182,20 +185,47 @@ export abstract class OrderGet extends OrderEntity { const comments: IComment[] = []; - for (const cmtId of cmts) { - const cmt = await this.Comment(cmtId); + if (admin) + for (const cmtId of cmts) { + const cmt = await AdminOrderEntity.Comment(cmtId); - if (!cmt) { - log.warn(`[Mismatch] Comment ${cmtId} not found. Order : ${orderId}`); - continue; + if (!cmt) { + log.warn(`[Mismatch] Comment ${cmtId} not found. Order : ${orderId}`); + continue; + } + + let name = "Client"; + + if (cmt.UserId) { + const user = await AdminUserEntity.User(cmt.UserId); + + if (user) + name = user.Name; + else + log.warn(`[Mismatch] User ${cmt.UserId} not found. Order : ${orderId}`); + } + + comments.push({ + Content: cmt.Content, + Time: cmt.CreateAt, + User: name + }); } + else + for (const cmtId of cmts) { + const cmt = await this.Comment(cmtId); - comments.push({ - Content: cmt.Content, - Time: cmt.CreateAt, - User: cmt.Name || "You" - }); - } + if (!cmt) { + log.warn(`[Mismatch] Comment ${cmtId} not found. Order : ${orderId}`); + continue; + } + + comments.push({ + Content: cmt.Content, + Time: cmt.CreateAt, + User: cmt.Name || "You" + }); + } setRes(comments.sort((a, b) => a.Time.getTime() - b.Time.getTime())); }, [req.data]); diff --git a/src/ShopNet/SignalR.ts b/src/ShopNet/SignalR.ts index af17a0e..7f42bca 100644 --- a/src/ShopNet/SignalR.ts +++ b/src/ShopNet/SignalR.ts @@ -11,12 +11,9 @@ import type { AdminNet } from "./Admin/AdminNet"; import { MSAL, Shared, type IConcurrency } from "./Database"; import type { ShopNet } from "./ShopNet"; -/** - * @author Aloento - * @since 1.0.0 - * @version 0.1.0 - */ -type INet = typeof ShopNet | typeof AdminNet; +export namespace SignalR { + export type INet = typeof ShopNet | typeof AdminNet; +} /** * @author Aloento @@ -29,7 +26,7 @@ export abstract class SignalR { * @since 1.0.0 * @version 0.1.1 */ - protected static async EnsureConnected(this: INet): Promise { + protected static async EnsureConnected(this: SignalR.INet): Promise { if (this.Hub.state === HubConnectionState.Connected) return Promise.resolve(); @@ -52,7 +49,7 @@ export abstract class SignalR { * @since 1.0.0 * @version 0.1.0 */ - protected static async Invoke(this: INet, methodName: string, ...args: any[]): Promise { + protected static async Invoke(this: SignalR.INet, methodName: string, ...args: any[]): Promise { await this.EnsureConnected(); return this.Hub.invoke(methodName, ...args); } @@ -62,7 +59,7 @@ export abstract class SignalR { * @since 1.0.0 * @version 0.2.1 */ - protected static EnsureLogin(this: INet) { + protected static EnsureLogin(this: SignalR.INet) { if (!MSAL.getActiveAccount()) throw new NotLoginError(); } @@ -72,7 +69,7 @@ export abstract class SignalR { * @since 1.0.0 * @version 0.1.0 */ - protected static EnsureTrue(this: INet, res: boolean | null | undefined): asserts res is true { + protected static EnsureTrue(this: SignalR.INet, res: boolean | null | undefined): asserts res is true { if (!res) throw new NotTrueError(); } @@ -82,7 +79,7 @@ export abstract class SignalR { * @since 1.0.0 * @version 0.1.2 */ - protected static async HandleFileStream(this: INet, file: File, subject: Subject, pLog: Logger) { + protected static async HandleFileStream(this: SignalR.INet, file: File, subject: Subject, pLog: Logger) { const chunkSize = 30 * 1024; const chunks = Math.ceil(file.size / chunkSize); let index = 0; @@ -152,7 +149,7 @@ export abstract class SignalR { * @liveSafe */ protected static async GetVersionCache( - this: INet, key: string | number, methodName: string + this: SignalR.INet, key: string | number, methodName: string ): Promise { const index = this.Index(key, methodName); await this.getLocker(index); @@ -208,7 +205,7 @@ export abstract class SignalR { * @deprecated Use {@link useTimeCache} if possible. */ protected static async GetTimeCache( - this: INet, key: string | number, methodName: string, exp: (now: Dayjs) => Dayjs, ...args: any[] + this: SignalR.INet, key: string | number, methodName: string, exp: (now: Dayjs) => Dayjs, ...args: any[] ): Promise { const index = this.Index(key, methodName); await this.getLocker(index); @@ -233,7 +230,7 @@ export abstract class SignalR { * @version 0.1.0 */ protected static useTimeCache( - this: INet, key: string | number, methodName: string, options: Options + this: SignalR.INet, key: string | number, methodName: string, options: Options ) { const index = useConst(() => this.Index(key, methodName)); @@ -253,7 +250,7 @@ export abstract class SignalR { * @deprecated */ protected static async UpdateCache( - this: INet, action: (raw: T) => T, key: string | number, methodName: string, exp?: Dayjs + this: SignalR.INet, action: (raw: T) => T, key: string | number, methodName: string, exp?: Dayjs ) { const index = this.Index(key, methodName); const find = await Shared.Get(index);