This commit is contained in:
focp212@naver.com
2025-09-29 16:59:34 +09:00
5 changed files with 80 additions and 53 deletions

View File

@@ -13,7 +13,7 @@ export const UserAccountAuthWrap = ({
}: UserAccountAuthWrapProps) => { }: UserAccountAuthWrapProps) => {
const [currentStatus, setCurrentStatus] = useState(status); const [currentStatus, setCurrentStatus] = useState(status);
const [currentIdCL, setCurrentIdCl] = useState(idCL); const [currentIdCL, setCurrentIdCl] = useState(idCL);
const [menuGrants, setMenuGrants] = useState<Array<UserMenuPermissionData>>([]); const [permissions, setPermissions] = useState<Array<UserMenuPermissionData>>([]);
const [hasChanges, setHasChanges] = useState(false); const [hasChanges, setHasChanges] = useState(false);
console.log('mid : ', mid); console.log('mid : ', mid);
console.log('usrid : ', usrid); console.log('usrid : ', usrid);
@@ -24,20 +24,21 @@ export const UserAccountAuthWrap = ({
useEffect(() => { useEffect(() => {
if (mid && usrid) { if (mid && usrid) {
console.log('userMenuPermissions'); console.log('userMenuPermissions');
userMenuPermissions({mid: mid, usrid: usrid}).then((res) => { userMenuPermissions({mid: mid, usrid: usrid}).then((res: any) => {
console.log('res : ', res); console.log('res : ', res);
setMenuGrants(res?.data || res || []); console.log('permissions : ', res?.permissions);
setPermissions(res?.permissions || []);
}).catch((error) => { }).catch((error) => {
console.error('Failed to fetch menu permissions:', error); console.error('Failed to fetch menu permissions:', error);
setMenuGrants([]); setPermissions([]);
}); });
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [mid, usrid]); }, [mid, usrid]);
useEffect(() => { useEffect(() => {
console.log('menuGrants : ', menuGrants); console.log('permissions : ', permissions);
}, [menuGrants]); }, [permissions]);
// 변경 사항 감지 // 변경 사항 감지
useEffect(() => { useEffect(() => {
@@ -81,7 +82,7 @@ export const UserAccountAuthWrap = ({
}, },
{menuId: '47', parent: '47', menuName: '부가세신고자료', subMenu: {menuId: '47', parent: '47', menuName: '부가세신고자료', subMenu:
[ [
{menuId: '48', parent: '47', menuName: '부가세신고자료'}, {menuId: '48', parent: '47', menuName: '세금계산서'},
{menuId: '49', parent: '47', menuName: '부가세참고'}, {menuId: '49', parent: '47', menuName: '부가세참고'},
] ]
}, },
@@ -89,14 +90,14 @@ export const UserAccountAuthWrap = ({
[ [
{menuId: '51', parent: '50', menuName: '부가서비스소개'}, {menuId: '51', parent: '50', menuName: '부가서비스소개'},
{menuId: '52', parent: '50', menuName: '신용카드ARS카드결제'}, {menuId: '52', parent: '50', menuName: '신용카드ARS카드결제'},
{menuId: '53', parent: '50', menuName: '계좌이체ARS카드결제'}, {menuId: '53', parent: '50', menuName: '지급대행'},
{menuId: '54', parent: '50', menuName: '가상계좌ARS카드결제'}, {menuId: '54', parent: '50', menuName: '링크결제'},
{menuId: '55', parent: '50', menuName: '휴대폰ARS카드결제'}, {menuId: '55', parent: '50', menuName: '자금이체'},
{menuId: '56', parent: '50', menuName: '계좌간편결제ARS카드결제'}, {menuId: '56', parent: '50', menuName: 'KEY-IN결제'},
{menuId: '57', parent: '50', menuName: 'SSG머니ARS카드결제'}, {menuId: '57', parent: '50', menuName: 'SMS결제통보'},
{menuId: '58', parent: '50', menuName: 'SSG은행계좌ARS카드결제'}, {menuId: '58', parent: '50', menuName: '알림톡결제통보'},
{menuId: '59', parent: '50', menuName: '문화상품권ARS카드결제'}, {menuId: '59', parent: '50', menuName: '계좌점유인증'},
{menuId: '60', parent: '50', menuName: '티머니페이ARS카드결제'}, {menuId: '60', parent: '50', menuName: '계좌성명조회'},
] ]
}, },
{menuId: '61', parent: '61', menuName: '고객지원', subMenu: {menuId: '61', parent: '61', menuName: '고객지원', subMenu:
@@ -139,7 +140,7 @@ export const UserAccountAuthWrap = ({
idCL={ currentIdCL } idCL={ currentIdCL }
status={ currentStatus } status={ currentStatus }
menuItems={ menuItems } menuItems={ menuItems }
menuGrants={ menuGrants } menuGrants={ permissions }
></UserAccountAuthPermList> ></UserAccountAuthPermList>
<div className="apply-row bottom-padding"> <div className="apply-row bottom-padding">

View File

@@ -115,8 +115,7 @@ export interface UserMenuPermissionsParams {
} }
export interface UserMenuPermissionsResponse { export interface UserMenuPermissionsResponse {
status: boolean; permissions: Array<UserMenuPermissionData>;
data: Array<UserMenuPermissionData>;
} }
export interface UserMenuPermissionsSaveParams { export interface UserMenuPermissionsSaveParams {
@@ -134,6 +133,7 @@ export interface UserMenuPermissionData {
menuId: number; menuId: number;
usrid: string; usrid: string;
grant: number; grant: number;
defaultGrant: number;
} }
export interface ChangePasswordParams { export interface ChangePasswordParams {

View File

@@ -14,14 +14,14 @@ import { snackBar } from '@/shared/lib/toast';
export const PasswordModifyCancelPasswordPage = () => { export const PasswordModifyCancelPasswordPage = () => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const [mid, setMid] = useState<string>('nictest00m'); const [mid, setMid] = useState<string>('nictest00m');
const [newPassword, setNewPassword] = useState<string>(''); const [password, setPassword] = useState<string>('');
const [confirmPassword, setConfirmPassword] = useState<string>(''); const [confirmPassword, setConfirmPassword] = useState<string>('');
const changeCancelPasswordMutation = useUserChangeCancelPasswordMutation({ const changeCancelPasswordMutation = useUserChangeCancelPasswordMutation({
onSuccess: () => { onSuccess: () => {
snackBar('비밀번호가 성공적으로 변경되었습니다.'); snackBar('비밀번호가 성공적으로 변경되었습니다.');
// Clear form // Clear form
setNewPassword(''); setPassword('');
setConfirmPassword(''); setConfirmPassword('');
// Navigate back // Navigate back
navigate(PATHS.account.password.manage); navigate(PATHS.account.password.manage);
@@ -32,6 +32,7 @@ export const PasswordModifyCancelPasswordPage = () => {
}); });
const midList = [ const midList = [
{ value: 'nictest00', label: 'nictest00' },
{ value: 'nictest00m', label: 'nictest00m' }, { value: 'nictest00m', label: 'nictest00m' },
{ value: 'nictest01m', label: 'nictest01m' }, { value: 'nictest01m', label: 'nictest01m' },
{ value: 'nictest02m', label: 'nictest02m' }, { value: 'nictest02m', label: 'nictest02m' },
@@ -47,9 +48,9 @@ export const PasswordModifyCancelPasswordPage = () => {
// 저장 버튼 활성화 조건 체크 // 저장 버튼 활성화 조건 체크
const isFormValid = () => { const isFormValid = () => {
return ( return (
newPassword.length >= 8 && password.length >= 8 &&
confirmPassword.length >= 8 && confirmPassword.length >= 8 &&
newPassword === confirmPassword password === confirmPassword
); );
}; };
@@ -60,7 +61,7 @@ export const PasswordModifyCancelPasswordPage = () => {
// TODO: Validate current password before submitting // TODO: Validate current password before submitting
changeCancelPasswordMutation.mutate({ changeCancelPasswordMutation.mutate({
mid, mid,
password: newPassword password: password
}); });
}; };
@@ -82,24 +83,24 @@ export const PasswordModifyCancelPasswordPage = () => {
<div className="ua-row"> <div className="ua-row">
<div className="ua-label"> <span className="red">*</span></div> <div className="ua-label"> <span className="red">*</span></div>
<input <input
className={`wid-100 ${confirmPassword && newPassword !== confirmPassword ? 'error' : ''}`} className={`wid-100 ${confirmPassword && password !== confirmPassword ? 'error' : ''}`}
type="password" type="password"
placeholder="" placeholder=""
value={newPassword} value={password}
onChange={(e) => setNewPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
/> />
</div> </div>
<div className="ua-row"> <div className="ua-row">
<div className="ua-label"> <span className="red">*</span></div> <div className="ua-label"> <span className="red">*</span></div>
<input <input
className={`wid-100 ${confirmPassword && newPassword !== confirmPassword ? 'error' : ''}`} className={`wid-100 ${confirmPassword && password !== confirmPassword ? 'error' : ''}`}
type="password" type="password"
placeholder="" placeholder=""
value={confirmPassword} value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)} onChange={(e) => setConfirmPassword(e.target.value)}
/> />
</div> </div>
{confirmPassword && newPassword !== confirmPassword && ( {confirmPassword && password !== confirmPassword && (
<div className="ua-help error"> </div> <div className="ua-help error"> </div>
)} )}
</div> </div>

View File

@@ -30,11 +30,19 @@ export const UserMenuAuthPage = () => {
// 메뉴별 권한 상태 관리 // 메뉴별 권한 상태 관리
const [permissions, setPermissions] = useState<Record<number, number>>({}); const [permissions, setPermissions] = useState<Record<number, number>>({});
const [initialPermissions, setInitialPermissions] = useState<Record<number, number>>({}); const [initialPermissions, setInitialPermissions] = useState<Record<number, number>>({});
const [defaultPermissions, setDefaultPermissions] = useState<Record<number, number>>({});
const [hasChanges, setHasChanges] = useState(false); const [hasChanges, setHasChanges] = useState(false);
const savePermissionsMutation = useUserMenuPermissionsSaveMutation({ const savePermissionsMutation = useUserMenuPermissionsSaveMutation({
onSuccess: () => { onSuccess: () => {
snackBar('권한이 성공적으로 저장되었습니다.'); snackBar('권한이 성공적으로 저장되었습니다.');
navigate(PATHS.account.password.manage); navigate(PATHS.account.user.accountAuth, {
state: {
mid,
usrid,
idCl: location.state?.idCl,
status: location.state?.status
}
});
}, },
onError: (error) => { onError: (error) => {
snackBar(error?.response?.data?.message || '권한 저장에 실패했습니다.'); snackBar(error?.response?.data?.message || '권한 저장에 실패했습니다.');
@@ -84,12 +92,15 @@ export const UserMenuAuthPage = () => {
useEffect(() => { useEffect(() => {
if (menuGrants && Array.isArray(menuGrants) && menuGrants.length > 0) { if (menuGrants && Array.isArray(menuGrants) && menuGrants.length > 0) {
// menuGrants 데이터가 있으면 사용 // menuGrants 데이터가 있으면 사용
const initial: Record<number, number> = {}; const grants: Record<number, number> = {};
menuGrants.forEach((grant: { menuId: number; grant: number }) => { const defaultGrants: Record<number, number> = {};
initial[grant.menuId] = grant.grant || 0; menuGrants.forEach((grant: { menuId: number; grant: number; defaultGrant: number }) => {
grants[grant.menuId] = grant.grant || 0;
defaultGrants[grant.menuId] = grant.defaultGrant || 0;
}); });
setPermissions(initial); setPermissions(grants);
setInitialPermissions(initial); setInitialPermissions(grants); // 초기값은 현재 grant 값으로 설정
setDefaultPermissions(defaultGrants); // defaultGrant는 별도로 관리
} else { } else {
// menuGrants가 없거나 빈 배열이면 API에서 권한 조회 // menuGrants가 없거나 빈 배열이면 API에서 권한 조회
// loadPermissions(); // loadPermissions();
@@ -114,6 +125,11 @@ export const UserMenuAuthPage = () => {
return (grant & flag) === flag; return (grant & flag) === flag;
}; };
const hasDefaultPermission = (menuId: number, flag: number): boolean => {
const grant = defaultPermissions[menuId] || 0;
return (grant & flag) === flag;
};
// 권한 토글 처리 // 권한 토글 처리
const togglePermission = (menuId: number, flag: number) => { const togglePermission = (menuId: number, flag: number) => {
setPermissions(prev => { setPermissions(prev => {
@@ -152,7 +168,8 @@ export const UserMenuAuthPage = () => {
([menuId, grant]) => ({ ([menuId, grant]) => ({
menuId: Number(menuId), menuId: Number(menuId),
usrid: usrid, usrid: usrid,
grant: grant grant: grant,
defaultGrant: defaultPermissions[Number(menuId)] || 0
}) })
); );
@@ -210,6 +227,7 @@ export const UserMenuAuthPage = () => {
}} }}
> >
<div className="set-divider"></div> <div className="set-divider"></div>
{hasDefaultPermission(menu.menuId, PERMISSION.SAVE) && (
<div className="settings-row"> <div className="settings-row">
<span className="settings-row-title bd-sub dot"></span> <span className="settings-row-title bd-sub dot"></span>
<label className="settings-switch"> <label className="settings-switch">
@@ -221,6 +239,9 @@ export const UserMenuAuthPage = () => {
<span className="slider"></span> <span className="slider"></span>
</label> </label>
</div> </div>
)}
{hasDefaultPermission(menu.menuId, PERMISSION.EXECUTE) && (
<div className="settings-row"> <div className="settings-row">
<span className="settings-row-title bd-sub dot"></span> <span className="settings-row-title bd-sub dot"></span>
<label className="settings-switch"> <label className="settings-switch">
@@ -232,6 +253,9 @@ export const UserMenuAuthPage = () => {
<span className="slider"></span> <span className="slider"></span>
</label> </label>
</div> </div>
)}
{hasDefaultPermission(menu.menuId, PERMISSION.DOWNLOAD) && (
<div className="settings-row"> <div className="settings-row">
<span className="settings-row-title bd-sub dot"></span> <span className="settings-row-title bd-sub dot"></span>
<label className="settings-switch"> <label className="settings-switch">
@@ -243,6 +267,7 @@ export const UserMenuAuthPage = () => {
<span className="slider"></span> <span className="slider"></span>
</label> </label>
</div> </div>
)}
</div> </div>
</div> </div>
<div className="ht-20"></div> <div className="ht-20"></div>

View File

@@ -42,6 +42,6 @@ export const API_URL_USER = {
return `${API_BASE_URL}/api/v1/${API_URL_KEY}/user/password`; return `${API_BASE_URL}/api/v1/${API_URL_KEY}/user/password`;
}, },
userChangeCancelPassword: () => { userChangeCancelPassword: () => {
return `${API_BASE_URL}/api/v1/${API_URL_KEY}/user/cancel/change`; return `${API_BASE_URL}/api/v1/${API_URL_KEY}/user/cancle/change`;
} }
} }