From d4565042255ca38e27627141c8e70b823228914d Mon Sep 17 00:00:00 2001 From: Hide_D Date: Sun, 3 Apr 2022 23:42:52 +0900 Subject: [PATCH] =?UTF-8?q?feat(WIP):=20=EC=84=B8=EB=A0=A5=EC=9E=A5?= =?UTF-8?q?=EC=88=98=20=EB=B3=80=EA=B2=BD=EC=82=AC=ED=95=AD=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/sammo/API/Nation/GeneralList.php | 8 +- hwe/templates/commandButton.php | 2 +- hwe/ts/PageNationGeneral.vue | 7 +- hwe/ts/SammoAPI.ts | 3 +- hwe/ts/components/GeneralList.vue | 434 +++++++++++++++++++-------- hwe/ts/defs/API/Nation.ts | 80 ++++- hwe/ts/defs/API/Nation/index.ts | 73 ----- 7 files changed, 397 insertions(+), 210 deletions(-) delete mode 100644 hwe/ts/defs/API/Nation/index.ts diff --git a/hwe/sammo/API/Nation/GeneralList.php b/hwe/sammo/API/Nation/GeneralList.php index 729cd701..62c9da17 100644 --- a/hwe/sammo/API/Nation/GeneralList.php +++ b/hwe/sammo/API/Nation/GeneralList.php @@ -11,6 +11,7 @@ use sammo\Validator; use function sammo\calcLeadershipBonus; use function sammo\checkLimit; use function sammo\checkSecretPermission; +use function sammo\getBillByLevel; use function sammo\getDedLevelText; use function sammo\getGenChar; use function sammo\getGeneralSpecialDomesticName; @@ -117,6 +118,8 @@ class GeneralList extends \sammo\BaseAPI 'lbonus' => 0, 'ownerName' => 0, 'honorText' => 0, + 'dedLevelText' => 0, + 'bill' => 0, ]; @@ -150,12 +153,13 @@ class GeneralList extends \sammo\BaseAPI return getHonor($rawGeneral['experience']); }, 'dedLevelText' => function ($rawGeneral) { - return getDedLevelText($rawGeneral['dedLevel']); + return getDedLevelText($rawGeneral['dedlevel']); }, 'turntime' => function ($rawGeneral) { //'0000-00-00 11:23'; return substr($rawGeneral['turntime'], 11, 5); - } + }, + 'bill' => fn($rawGeneral) => getBillByLevel($rawGeneral['dedlevel']) ]; diff --git a/hwe/templates/commandButton.php b/hwe/templates/commandButton.php index 4da7e7bb..834c55e4 100644 --- a/hwe/templates/commandButton.php +++ b/hwe/templates/commandButton.php @@ -10,7 +10,7 @@ 토 너 먼 트 '>세력 정보 '>세력 도시 -'>세력 장수 +'>세력 장수 중원 정보 현재 도시 '>감 찰 부 diff --git a/hwe/ts/PageNationGeneral.vue b/hwe/ts/PageNationGeneral.vue index 5e83e4b7..9c8b1d02 100644 --- a/hwe/ts/PageNationGeneral.vue +++ b/hwe/ts/PageNationGeneral.vue @@ -1,7 +1,12 @@ diff --git a/hwe/ts/SammoAPI.ts b/hwe/ts/SammoAPI.ts index 927720e6..1b87fd83 100644 --- a/hwe/ts/SammoAPI.ts +++ b/hwe/ts/SammoAPI.ts @@ -9,7 +9,7 @@ import type { BettingDetailResponse, BettingListResponse } from "./defs/API/Bett import type { ReserveBulkCommandResponse, ReserveCommandResponse, ReservedCommandResponse } from "./defs/API/Command"; import type { ChiefResponse } from "./defs/API/NationCommand"; import type { inheritBuffType } from "./defs/API/InheritAction"; -import type { SetBlockWarResponse } from "./defs/API/Nation"; +import type { SetBlockWarResponse, GeneralListResponse as NationGeneralListResponse } from "./defs/API/Nation"; import type { UploadImageResponse } from "./defs/API/Misc"; import type { JoinArgs } from "./defs/API/General"; import type { GetConstResponse } from "./defs/API/Global"; @@ -96,6 +96,7 @@ const apiRealPath = { }[], ReserveBulkCommandResponse>, }, Nation: { + GeneralList: GET as APICallT, SetNotice: PUT as APICallT<{ msg: string, }>, diff --git a/hwe/ts/components/GeneralList.vue b/hwe/ts/components/GeneralList.vue index 0860fd45..470153ff 100644 --- a/hwe/ts/components/GeneralList.vue +++ b/hwe/ts/components/GeneralList.vue @@ -8,6 +8,7 @@ , + type: String as PropType<"static" | "fill" | number | `${number}px` | `${number}%`>, required: false, - default: 'static', + default: "static", }, }); +//debug +console.log(`list`, props.list); + watch( () => props.list, () => { setTimeout(() => { + //debug + console.log(`list`, props.list); gridApi.value?.redrawRows(); }, 0); } @@ -50,7 +69,7 @@ watch( watch( () => props.height, (val) => { - if (val === 'static') { + if (val === "static") { gridApi.value?.setDomLayout("autoHeight"); } else { gridApi.value?.setDomLayout("normal"); @@ -63,76 +82,106 @@ const columnApi = ref(); const rowHeight = ref(28); +function getRowId(params: GetRowIdParams): string { + const genID = (params.data as GeneralListItem).no; + return `${genID}`; +} + function onGridReady(params: GridReadyEvent) { gridApi.value = params.api; columnApi.value = params.columnApi; - if (props.height === 'static') { + if (props.height === "static") { params.api.setDomLayout("autoHeight"); - } - else{ - params.api.setDomLayout('normal'); + } else { + params.api.setDomLayout("normal"); } setRowHeight(); - params.api.sizeColumnsToFit(); } function setRowHeight() { - if (!columnRawDefs.value.icon?.hide) { + if (!(columnRawDefs.value.icon as GenColDef | undefined)?.hide) { rowHeight.value = 64 + 4; return; } rowHeight.value = gridApi.value?.getSizesForCurrentTheme().rowHeight ?? 28; } -type headerInfo = { - title: string; - info?: string; - isEnum?: boolean; //default: false - sortable?: "asc" | "desc" | false | undefined | null; //default: false - searchable?: boolean; //default: false - type?: "both" | "display" | "filter" | "custom"; //default: both - converter?: (a: GeneralListItem) => string; - subType?: Partial>; //n행 표기 시 - style?: StyleValue; -}; - type headerType = - | keyof Omit + | keyof Omit | "stat" | "icon" | "goldRice" | "expDedLv" | "specials" - | "killturnAndConnect"; + | "killturnAndConnect" + | "years"; -type GenColDef = ColDef & { +interface GenValueParams extends BaseWithValueColDefParams { + data: GeneralListItem; +} + +interface GenValueGetterParams extends ValueGetterParams { + data: GeneralListItem; +} + +interface GenColDef extends ColDef { field?: headerType; -}; + valueFormatter?: string | ((params: GenValueParams) => string); + filterValueGetter?: string | ((params: GenValueGetterParams) => string); +} + +interface GenColGroupDef extends ColGroupDef { + children: (GenColDef | GenColGroupDef)[]; + groupId: headerType; +} interface GenCellClassParams extends CellClassParams { data: GeneralListItem; } +function naiveCheClassNameFilter(value: string): string { + const text = value.split("_").pop() ?? "None"; + if (text === "None") { + return "-"; + } + return text; +} + +function naiveCheClassNameFilterFromRow(key: keyof GeneralListItem) { + return (value: GenValueParams): string => { + return naiveCheClassNameFilter(value.data[key]?.toString() ?? "None"); + }; +} + +function numberFormatter(value: GenValueParams): string { + return (value.value as number).toLocaleString(); +} + +const defaultCellClass = ["cell-middle"]; +const centerCellClass = [...defaultCellClass, "cell-center"]; +const rightAlignClass = [...defaultCellClass, "cell-right"]; +const sortableNumber: GenColDef = { + sortable: true, + comparator: (a, b) => a - b, + sortingOrder: ["desc", "asc", null], + filter: "number", + cellClass: rightAlignClass, +}; const defaultColDef = ref({ resizable: true, headerClass: "default-cell-header", - cellClass: "cell-middle", + cellClass: centerCellClass, + floatingFilter: true, + width: 90, }); -const sortableNumber: GenColDef = { - sortable: true, - comparator: (a, b)=>a-b, - sortingOrder: ['desc', 'asc', null], - filter: 'number' -} - -const columnRawDefs = ref>>({ +const columnRawDefs = ref>>({ icon: { headerName: "아이콘", width: 64 + 24, suppressSizeToFit: true, resizable: false, - cellRenderer: (obj: { data: GeneralListItem }) => { + cellRenderer: (obj: GenValueParams) => { const { data: gen } = obj; return ``; }, @@ -144,7 +193,8 @@ const columnRawDefs = ref>>({ field: "name", pinned: "left", sortable: true, - sortingOrder: ['asc', 'desc', null], + width: 130, + sortingOrder: ["asc", "desc", null], lockPosition: true, cellStyle: (val: GenCellClassParams) => { const gen = val.data; @@ -153,117 +203,229 @@ const columnRawDefs = ref>>({ }; return style as CellStyle; }, + cellClass: defaultCellClass, filter: true, }, npc: { headerName: "NPC", field: "npc", hide: true }, - leadership: { headerName: '통솔', field: 'leadership', ...sortableNumber}, - strength: { headerName: '무력', field: 'strength', ...sortableNumber}, - intel: { headerName: '지력', field: 'intel', ...sortableNumber}, - explevel: { headerName: '명성Lv', field: 'explevel', ...sortableNumber}, - dedlevel: { headerName: '계급Lv', field: 'dedlevel', ...sortableNumber}, + stat: { + groupId: "stat", + openByDefault: false, + headerName: "능력치", + children: [ + { + headerName: "통|무|지", + width: 90, + + cellRenderer: (obj: GenValueParams) => { + const gen = obj.data; + return `${gen.leadership}|${gen.strength}|${gen.intel}`; + }, + columnGroupShow: "closed", + }, + { + headerName: "통솔", + field: "leadership", + ...sortableNumber, + columnGroupShow: "open", + width: 70, + type: "numericColumn", + }, + { + headerName: "무력", + field: "strength", + ...sortableNumber, + columnGroupShow: "open", + width: 70, + }, + { + headerName: "지력", + field: "intel", + ...sortableNumber, + columnGroupShow: "open", + width: 70, + }, + ], + }, + officerLevel: { + headerName: "관직", + field: "officerLevelText", + sortable: true, + comparator: (a, b, c, d) => c.data.officerLevel - d.data.officerLevel, + cellRenderer: ({ data }: GenValueParams) => { + if (data.permission == 2 && 2 <= data.officerLevel && 4 <= data.officerLevel) { + return `${data.officer_city} ${data.officerLevelText}`; + } + return data.officerLevelText; + }, + filter: true, + cellClass: centerCellClass, + width: 90, + }, + expDedLv: { + headerName: "명성", + groupId: "expDedLv", + width: 70, + children: [ + { + headerName: "/계급", + columnGroupShow: "closed", + width: 70, + cellRenderer: ({ data }: GenValueParams) => { + return `Lv ${data.explevel}
${data.dedLevelText}`; + }, + }, + { + headerName: "명성", + field: "explevel", + width: 75, + cellRenderer: ({ data }: GenValueParams) => { + return `Lv ${data.explevel}
(${data.honorText})`; + }, + ...sortableNumber, + columnGroupShow: "open", + }, + { + headerName: "계급", + field: "dedLevelText", + width: 75, + cellRenderer: ({ data }: GenValueParams) => { + return `${data.dedLevelText}
(${data.bill.toLocaleString()})`; + }, + ...sortableNumber, + cellClass: centerCellClass, + columnGroupShow: "open", + }, + ], + }, + gold: { headerName: "금", field: "gold", ...sortableNumber, valueFormatter: numberFormatter, width: 75 }, + rice: { headerName: "쌀", field: "rice", ...sortableNumber, valueFormatter: numberFormatter, width: 75 }, + + specials: { + headerName: "성격/내특/전특", + children: [ + { + headerName: "요약", + cellRenderer: ({ data }: GenValueParams) => { + const personal = naiveCheClassNameFilter(data.personal); + const specialDomestic = naiveCheClassNameFilter(data.specialDomestic); + const specialWar = naiveCheClassNameFilter(data.specialWar); + return `${personal}
${specialDomestic}
${specialWar}
`; + }, + width: 90, + columnGroupShow: "closed", + }, + { + headerName: "성격", + field: "personal", + valueFormatter: naiveCheClassNameFilterFromRow("personal"), + width: 70, + sortable: true, + filter: true, + columnGroupShow: "open", + }, + { + headerName: "내특", + field: "specialDomestic", + valueFormatter: naiveCheClassNameFilterFromRow("specialDomestic"), + width: 70, + sortable: true, + filter: true, + columnGroupShow: "open", + }, + { + headerName: "전특", + field: "specialWar", + valueFormatter: naiveCheClassNameFilterFromRow("specialWar"), + width: 70, + sortable: true, + filter: true, + columnGroupShow: "open", + }, + ], + }, + years: { + headerName: "연도", + children: [ + { + headerName: "요약", + cellRenderer: ({ data }: GenValueParams) => { + return `${data.age}세
${data.belong}년`; + }, + cellClass: centerCellClass, + columnGroupShow: "closed", + }, + { + headerName: "연령", + field: "age", + ...sortableNumber, + valueFormatter: (v: GenValueParams) => `${v.value}세`, + width: 70, + cellClass: centerCellClass, + columnGroupShow: "open", + }, + { + headerName: "사관", + field: "belong", + ...sortableNumber, + valueFormatter: (v: GenValueParams) => `${v.value}년`, + width: 70, + cellClass: centerCellClass, + columnGroupShow: "open", + }, + ], + }, + killturnAndConnect: { + headerName: "기타", + children: [ + { + headerName: "삭/벌", + cellRenderer: ({ data }: GenValueParams) => { + return `${data.killturn.toLocaleString()}턴
${data.connect.toLocaleString()}점`; + }, + cellClass: rightAlignClass, + columnGroupShow: "closed", + }, + { + headerName: "삭턴", + field: "killturn", + cellRenderer: ({ data }: GenValueParams) => { + return `${data.killturn.toLocaleString()}턴`; + }, + ...sortableNumber, + columnGroupShow: "open", + }, + { + headerName: "벌점", + field: "connect", + cellRenderer: ({ data }: GenValueParams) => { + return `${data.connect.toLocaleString()}점`; + }, + ...sortableNumber, + columnGroupShow: "open", + }, + ], + }, }); const columnDefs = ref([...Object.values(columnRawDefs.value)]); -const headerMap: Record = { - icon: { - title: "아이콘", - type: "display", - style: { - maxWidth: "64px", - }, - converter: (gen) => { - return ``; - }, - }, - name: { title: "장수명", searchable: true }, - nation: { title: "국가명", isEnum: true }, - npc: { title: "NPC", isEnum: true, type: "filter" }, - injury: { title: "부상", sortable: "asc" }, - leadership: { title: "통솔" }, - strength: { title: "무력" }, - intel: { title: "지력" }, - stat: { - title: "통/무/지", - type: "custom", - subType: { - leadership: { title: "통" }, - strength: { title: "무" }, - intel: { title: "지" }, - }, - }, - explevel: { title: "명성Lv" }, - dedlevel: { title: "계급Lv" }, - expDedLv: { - title: "명성/계급Lv", - subType: { - explevel: { title: "명성Lv" }, - dedlevel: { title: "계급Lv" }, - }, - }, - gold: { title: "금", sortable: "desc" }, - rice: { title: "쌀", sortable: "desc" }, - goldRice: { - title: "금/쌀", - type: "custom", - subType: { - gold: { title: "금", sortable: "desc" }, - rice: { title: "쌀", sortable: "desc" }, - }, - }, - age: { title: "연령" }, - specialDomestic: { title: "내특" }, - specialWar: { title: "전특" }, - specials: { - title: "성격/내특/전특", - subType: { - personal: { title: "성격", converter: (g) => g.personal.split("_").pop() as string }, - specialDomestic: { title: "내특", converter: (g) => g.specialDomestic.split("_").pop() as string }, - specialWar: { title: "전특", converter: (g) => g.specialWar.split("_").pop() as string }, - }, - }, - personal: { title: "성격" }, - belong: { title: "임관" }, - - killturnAndConnect: { - title: "삭턴/벌점", - subType: { - killturn: { title: "삭턴" }, - connect: { title: "벌점" }, - }, - }, - killturn: { title: "삭턴" }, - connect: { title: "벌점" }, - - officerLevel: { title: "관직" }, //권한에따라 태수,군사,시종 노출 여부가 다름 - ownerName: { title: "소유주" }, //NPC 출력용에 따라 결과가 다름 - honorText: { title: "명성" }, - - city: { title: "도시" }, - experience: { title: "명성" }, - dedication: { title: "계급" }, - - officer_level: { title: "관직" }, - officer_city: { title: "부임지" }, -} as const; - watch(columnRawDefs, (val) => { setRowHeight(); columnDefs.value = [...Object.values(val)]; }); - +/* let currentWidth = -1; window.addEventListener("resize", (e) => { setTimeout(() => { const newWidth = document.querySelector(".container")?.clientWidth ?? -1; if (currentWidth != newWidth) { currentWidth = newWidth; - gridApi.value?.sizeColumnsToFit(); + columnApi.value?.autoSizeAllColumns(); } }, 1); }); - +*/ diff --git a/hwe/ts/defs/API/Nation.ts b/hwe/ts/defs/API/Nation.ts index 6b4023c1..73dec09b 100644 --- a/hwe/ts/defs/API/Nation.ts +++ b/hwe/ts/defs/API/Nation.ts @@ -1,5 +1,79 @@ -import type { ValidResponse } from "@/defs"; +import type { ValuesOf, TurnObj } from "@/defs"; +import type { GameObjClassKey } from "@/defs/GameObj"; +import type { ValidResponse } from "@/SammoAPI"; export type SetBlockWarResponse = ValidResponse & { - availableCnt: number; - }; \ No newline at end of file + availableCnt: number; +}; + +export type GeneralListItemP0 = { + no: number, + name: string, + nation: number, + npc: number, + injury: number, + leadership: number, + strength: number, + intel: number, + explevel: number, + dedlevel: number, + gold: number, + rice: number, + killturn: number, + picture: string, + imgsvr: 0 | 1, + age: number, + specialDomestic: GameObjClassKey, + specialWar: GameObjClassKey, + personal: GameObjClassKey, + belong: number, + connect: number, + + officerLevel: number, //권한에따라 태수,군사,시종 노출 여부가 다름 + officerLevelText: string, + lbonus: number, + ownerName: string | null, //NPC 출력용에 따라 결과가 다름 + honorText: string, + dedLevelText: string, + bill: number, +} + +export type GeneralListItemP1 = { + city: number, + experience: number, + dedication: number, +} & GeneralListItemP0; + +export type GeneralListItemP2 = GeneralListItemP1 & { + officer_level: number, + officer_city: number, + +} + +export type RawGeneralListItem = GeneralListItemP0 | GeneralListItemP1 | GeneralListItemP2; + +export type GeneralListItem = + ({ permission: 0 } & GeneralListItemP0) | + ({ permission: 1 } & GeneralListItemP1) | + ({ permission: 2 | 3 | 4 } & GeneralListItemP2); + + +export type RawGeneralListP0 = ValidResponse & { + permission: 0, + column: (keyof GeneralListItemP0)[], + list: ValuesOf[][], +} + +export type RawGeneralListP1 = ValidResponse & { + permission: 1, + column: (keyof GeneralListItemP1)[], + list: ValuesOf[][], +} + +export type RawGeneralListP2 = ValidResponse & { + permission: 2 | 3 | 4, + column: (keyof GeneralListItemP2)[], + list: ValuesOf[][], +} + +export type GeneralListResponse = RawGeneralListP0 | RawGeneralListP1 | RawGeneralListP2; diff --git a/hwe/ts/defs/API/Nation/index.ts b/hwe/ts/defs/API/Nation/index.ts deleted file mode 100644 index a89dab15..00000000 --- a/hwe/ts/defs/API/Nation/index.ts +++ /dev/null @@ -1,73 +0,0 @@ - -import type { GameObjType, ValuesOf } from "@/defs"; -import type { ValidResponse } from "@/SammoAPI"; - -export type GeneralListItemP0 = { - no: number, - name: string, - nation: number, - npc: number, - injury: number, - leadership: number, - strength: number, - intel: number, - explevel: number, - dedlevel: number, - gold: number, - rice: number, - killturn: number, - picture: string, - imgsvr: 0 | 1, - age: number, - specialDomestic: GameObjType, - specialWar: GameObjType, - personal: GameObjType, - belong: number, - connect: number, - - officerLevel: number, //권한에따라 태수,군사,시종 노출 여부가 다름 - officerLevelText: string, - lbonus: number, - ownerName: string | null, //NPC 출력용에 따라 결과가 다름 - honorText: string, -} - -export type GeneralListItemP1 = { - city: number, - experience: number, - dedication: number, -} & GeneralListItemP0; - -export type GeneralListItemP2 = GeneralListItemP1 & { - officer_level: number, - officer_city: number, - -} - -export type RawGeneralListItem = GeneralListItemP0 | GeneralListItemP1 | GeneralListItemP2; - -export type GeneralListItem = - ({ permission: 0 } & GeneralListItemP0) | - ({ permission: 1 } & GeneralListItemP1) | - ({ permission: 2 | 3 | 4 } & GeneralListItemP2); - - -export type RawGeneralListP0 = ValidResponse & { - permission: 0, - column: (keyof GeneralListItemP0)[], - list: ValuesOf[][], -} - -export type RawGeneralListP1 = ValidResponse & { - permission: 1, - column: (keyof GeneralListItemP1)[], - list: ValuesOf[][], -} - -export type RawGeneralListP2 = ValidResponse & { - permission: 2 | 3 | 4, - column: (keyof GeneralListItemP2)[], - list: ValuesOf[][], -} - -export type GeneralListResponse = RawGeneralListP0 | RawGeneralListP1 | RawGeneralListP2;