[st] refactor: 알림톡발송 코드 분리
This commit is contained in:
@@ -3,9 +3,7 @@
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
type ColumnDef,
|
||||
getCoreRowModel,
|
||||
type RowSelectionState,
|
||||
useReactTable,
|
||||
@@ -14,17 +12,21 @@ import {
|
||||
import { client } from "@/shared/api/client";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import type { PageableList } from "@/shared/model";
|
||||
import {
|
||||
type AdstZoneResponseDto,
|
||||
type BusinessSendRequest,
|
||||
type BusinessSendResponse,
|
||||
type SelectedRecipient,
|
||||
type SewerStUserItem,
|
||||
useNtftalkTemplateList,
|
||||
useNtftalkTemplateVariables,
|
||||
userListColumns,
|
||||
useSewerStUserList,
|
||||
useStAnlsSidoCombo,
|
||||
useStAnlsSigunguCombo,
|
||||
} from "@/entities/statistics";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
DataTable,
|
||||
Dialog,
|
||||
DialogClose,
|
||||
@@ -49,35 +51,6 @@ import {
|
||||
TableRow,
|
||||
} from "@common/components";
|
||||
|
||||
interface NtftalkTemplate {
|
||||
templateCode: string;
|
||||
templateName: string;
|
||||
templateContent: string;
|
||||
}
|
||||
|
||||
interface TemplateVariablesResponse {
|
||||
templateCode: string;
|
||||
variables: string[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
interface BusinessSendRequest {
|
||||
templateCode: string;
|
||||
callback?: string;
|
||||
fixedRecipientNum?: string;
|
||||
recipients: Record<string, string>[];
|
||||
}
|
||||
|
||||
interface BusinessSendResponse {
|
||||
success: boolean;
|
||||
sentCount: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
interface SelectedRecipient extends SewerStUserItem {
|
||||
variableOverrides: Record<string, string>;
|
||||
}
|
||||
|
||||
type CommonVariableKey =
|
||||
| "userNm"
|
||||
| "sido"
|
||||
@@ -94,14 +67,6 @@ const GUBUN_OPTIONS = [
|
||||
{ value: "IDFR", label: "승인자" },
|
||||
{ value: "MCTPV", label: "검토자" },
|
||||
] as const;
|
||||
const DEFAULT_TEMPLATE_PARAMS = {
|
||||
sort: "createdAt,desc",
|
||||
senderKey: "",
|
||||
inspectionStatus: "APR",
|
||||
templateMessageType: "BA",
|
||||
page: 0,
|
||||
size: 10,
|
||||
};
|
||||
|
||||
function getDefaultStatsYear(): string {
|
||||
return String(new Date().getFullYear() - 1);
|
||||
@@ -161,38 +126,11 @@ function NtitlkSndng() {
|
||||
const [userListRowSelection, setUserListRowSelection] =
|
||||
useState<RowSelectionState>({});
|
||||
|
||||
const { data: templatePageData } = useQuery({
|
||||
queryKey: [
|
||||
ENDPOINT.NTFTALK_SERVICE.TEMP,
|
||||
"ntitlk-sndng",
|
||||
DEFAULT_TEMPLATE_PARAMS,
|
||||
],
|
||||
queryFn: async () => {
|
||||
const response = await client.get<PageableList<NtftalkTemplate>>(
|
||||
ENDPOINT.NTFTALK_SERVICE.TEMP,
|
||||
{ params: DEFAULT_TEMPLATE_PARAMS },
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
});
|
||||
|
||||
const { data: templatePageData } = useNtftalkTemplateList();
|
||||
const templates = templatePageData?.content ?? [];
|
||||
|
||||
const { data: templateVariablesData } = useQuery({
|
||||
queryKey: [
|
||||
ENDPOINT.NTFTALK_SERVICE.ATA_SEND,
|
||||
"template-variables",
|
||||
selectedTemplateCode,
|
||||
],
|
||||
queryFn: async () => {
|
||||
const response = await client.get<TemplateVariablesResponse>(
|
||||
`${ENDPOINT.NTFTALK_SERVICE.ATA_SEND}/template-variables/${selectedTemplateCode}`,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
enabled: Boolean(selectedTemplateCode),
|
||||
});
|
||||
|
||||
const { data: templateVariablesData } =
|
||||
useNtftalkTemplateVariables(selectedTemplateCode);
|
||||
const variableNames = templateVariablesData?.variables ?? [];
|
||||
|
||||
const { data: sidoData } = useStAnlsSidoCombo();
|
||||
@@ -203,80 +141,6 @@ function NtitlkSndng() {
|
||||
const { data: userListResponse, isLoading: isUserListLoading } =
|
||||
useSewerStUserList(appliedParams);
|
||||
const userList = (userListResponse as unknown as SewerStUserItem[]) ?? [];
|
||||
const userListColumns = useMemo<ColumnDef<SewerStUserItem>[]>(
|
||||
() => [
|
||||
{
|
||||
id: "select",
|
||||
header: ({ table }) => (
|
||||
<div
|
||||
className="flex justify-center"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
role="presentation"
|
||||
>
|
||||
<Checkbox
|
||||
checked={
|
||||
table.getIsAllPageRowsSelected() ||
|
||||
(table.getIsSomePageRowsSelected() &&
|
||||
"indeterminate")
|
||||
}
|
||||
onCheckedChange={(value) =>
|
||||
table.toggleAllPageRowsSelected(!!value)
|
||||
}
|
||||
aria-label="전체 선택"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<div
|
||||
className="flex justify-center"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
role="presentation"
|
||||
>
|
||||
<Checkbox
|
||||
checked={row.getIsSelected()}
|
||||
onCheckedChange={(value) =>
|
||||
row.toggleSelected(!!value)
|
||||
}
|
||||
aria-label="행 선택"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
{
|
||||
accessorKey: "userNm",
|
||||
header: "이름",
|
||||
},
|
||||
{
|
||||
accessorKey: "sido",
|
||||
header: "시도",
|
||||
},
|
||||
{
|
||||
accessorKey: "gugun",
|
||||
header: "시군구",
|
||||
},
|
||||
{
|
||||
accessorKey: "gubunNm",
|
||||
header: "구분",
|
||||
},
|
||||
{
|
||||
accessorKey: "deptNm",
|
||||
header: "소속",
|
||||
},
|
||||
{
|
||||
accessorKey: "jbgdNm",
|
||||
header: "직급",
|
||||
},
|
||||
{
|
||||
accessorKey: "telNo",
|
||||
header: "전화번호",
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
const userListTable = useReactTable({
|
||||
data: userList,
|
||||
columns: userListColumns,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { client } from "@/shared/api/client";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type { PageableList } from "@/shared/model";
|
||||
|
||||
import type {
|
||||
NtftalkTemplate,
|
||||
TemplateVariablesResponse,
|
||||
} from "../../model/notice-talk/notice-talk-sending-interface";
|
||||
|
||||
export const NTFTALK_TEMPLATE_LIST_PARAMS = {
|
||||
sort: "createdAt,desc",
|
||||
senderKey: "",
|
||||
inspectionStatus: "APR",
|
||||
templateMessageType: "BA",
|
||||
page: 0,
|
||||
size: 10,
|
||||
};
|
||||
|
||||
/**
|
||||
* 알림톡 발송 화면용 Ntftalk API
|
||||
*/
|
||||
export class NoticeTalkSendingApiService {
|
||||
async getTemplatePage(
|
||||
params: typeof NTFTALK_TEMPLATE_LIST_PARAMS = NTFTALK_TEMPLATE_LIST_PARAMS,
|
||||
): Promise<PageableList<NtftalkTemplate>> {
|
||||
const response = await client.get<PageableList<NtftalkTemplate>>(
|
||||
ENDPOINT.NTFTALK_SERVICE.TEMP,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async getTemplateVariables(
|
||||
templateCode: string,
|
||||
): Promise<TemplateVariablesResponse> {
|
||||
const response = await client.get<TemplateVariablesResponse>(
|
||||
`${ENDPOINT.NTFTALK_SERVICE.ATA_SEND}/template-variables/${templateCode}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const noticeTalkSendingApi = new NoticeTalkSendingApiService();
|
||||
@@ -0,0 +1,33 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
|
||||
import {
|
||||
noticeTalkSendingApi,
|
||||
NTFTALK_TEMPLATE_LIST_PARAMS,
|
||||
} from "./notice-talk-sending-service";
|
||||
|
||||
export function useNtftalkTemplateList() {
|
||||
return useQuery({
|
||||
queryKey: [
|
||||
ENDPOINT.NTFTALK_SERVICE.TEMP,
|
||||
"ntitlk-sndng",
|
||||
NTFTALK_TEMPLATE_LIST_PARAMS,
|
||||
],
|
||||
queryFn: () =>
|
||||
noticeTalkSendingApi.getTemplatePage(NTFTALK_TEMPLATE_LIST_PARAMS),
|
||||
});
|
||||
}
|
||||
|
||||
export function useNtftalkTemplateVariables(templateCode: string) {
|
||||
return useQuery({
|
||||
queryKey: [
|
||||
ENDPOINT.NTFTALK_SERVICE.ATA_SEND,
|
||||
"template-variables",
|
||||
templateCode,
|
||||
],
|
||||
queryFn: () =>
|
||||
noticeTalkSendingApi.getTemplateVariables(templateCode),
|
||||
enabled: Boolean(templateCode),
|
||||
});
|
||||
}
|
||||
@@ -8,6 +8,11 @@ export {
|
||||
export { dashboardApi } from "./api/dashboard/dashboard-service";
|
||||
export { useScheduleInfo } from "./api/dashboard/schedule-info-queries";
|
||||
export { scheduleInfoApi } from "./api/dashboard/schedule-info-service";
|
||||
export { noticeTalkSendingApi } from "./api/notice-talk/notice-talk-sending-service";
|
||||
export {
|
||||
useNtftalkTemplateList,
|
||||
useNtftalkTemplateVariables,
|
||||
} from "./api/notice-talk/queries";
|
||||
export {
|
||||
useSewerStUserList,
|
||||
useStAnlsSidoCombo,
|
||||
@@ -64,6 +69,14 @@ export {
|
||||
} from "./model/imr/imr-interface";
|
||||
export { imrVerificationHistoryColumns } from "./model/imr/imr-verification-history-columns";
|
||||
export { type StatsInputStatusList } from "./model/input/statistics-input-status-interface";
|
||||
export { userListColumns } from "./model/notice-talk/notice-talk-sending-columns";
|
||||
export {
|
||||
type BusinessSendRequest,
|
||||
type BusinessSendResponse,
|
||||
type NtftalkTemplate,
|
||||
type SelectedRecipient,
|
||||
type TemplateVariablesResponse,
|
||||
} from "./model/notice-talk/notice-talk-sending-interface";
|
||||
export {
|
||||
type SewerStUserItem,
|
||||
type SewerStUserListResponse,
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import type { ColumnDef } from "@tanstack/react-table";
|
||||
|
||||
import { Checkbox } from "@common/components";
|
||||
|
||||
import type { SewerStUserItem } from "../sewer-st-user-interface";
|
||||
|
||||
export const userListColumns: ColumnDef<SewerStUserItem>[] = [
|
||||
{
|
||||
id: "select",
|
||||
header: ({ table }) => (
|
||||
<div
|
||||
className="flex justify-center"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
role="presentation"
|
||||
>
|
||||
<Checkbox
|
||||
checked={
|
||||
table.getIsAllPageRowsSelected() ||
|
||||
(table.getIsSomePageRowsSelected() && "indeterminate")
|
||||
}
|
||||
onCheckedChange={(value) =>
|
||||
table.toggleAllPageRowsSelected(!!value)
|
||||
}
|
||||
aria-label="전체 선택"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<div
|
||||
className="flex justify-center"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
role="presentation"
|
||||
>
|
||||
<Checkbox
|
||||
checked={row.getIsSelected()}
|
||||
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
||||
aria-label="행 선택"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
{
|
||||
accessorKey: "userNm",
|
||||
header: "이름",
|
||||
},
|
||||
{
|
||||
accessorKey: "sido",
|
||||
header: "시도",
|
||||
},
|
||||
{
|
||||
accessorKey: "gugun",
|
||||
header: "시군구",
|
||||
},
|
||||
{
|
||||
accessorKey: "gubunNm",
|
||||
header: "구분",
|
||||
},
|
||||
{
|
||||
accessorKey: "deptNm",
|
||||
header: "소속",
|
||||
},
|
||||
{
|
||||
accessorKey: "jbgdNm",
|
||||
header: "직급",
|
||||
},
|
||||
{
|
||||
accessorKey: "telNo",
|
||||
header: "전화번호",
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { SewerStUserItem } from "../sewer-st-user-interface";
|
||||
|
||||
export interface NtftalkTemplate {
|
||||
templateCode: string;
|
||||
templateName: string;
|
||||
templateContent: string;
|
||||
}
|
||||
|
||||
export interface TemplateVariablesResponse {
|
||||
templateCode: string;
|
||||
variables: string[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface BusinessSendRequest {
|
||||
templateCode: string;
|
||||
callback?: string;
|
||||
fixedRecipientNum?: string;
|
||||
recipients: Record<string, string>[];
|
||||
}
|
||||
|
||||
export interface BusinessSendResponse {
|
||||
success: boolean;
|
||||
sentCount: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface SelectedRecipient extends SewerStUserItem {
|
||||
variableOverrides: Record<string, string>;
|
||||
}
|
||||
Reference in New Issue
Block a user