feat: MappingEngine + Override 실제 로직 + 프론트 주요 화면

Backend:
- MappingEngine: company_field_mapping 기반 동적 변환 구현
  - raw_content(JSON) → 표준 원장 (TRIM/UPPER/LOWER/DATE/DIVIDE/MULTIPLY/CODE_MAP)
  - policy_no 로 contract 매칭 → contract_id/agent_id 자동
  - 실패 시 parse_error_log 자동 적재
- Recruit/Maintain Mapper.sumByAgentMonth 추가
- OrganizationMapper.selectAncestorIds (CTE 재귀 상향) 추가
- CalcOverrideStep 실제 동작:
  * lower agent 의 모집+유지 합계를 base 로 사용
  * 자기 조직 → 상위 조직 순으로 to_grade 직급 ACTIVE 설계사 탐색
  * (lowerOrgId, toGrade) 캐싱

Frontend (주요 화면):
- 공통 컴포넌트:
  * CodeSelect (공통코드 드롭다운, React Query 캐시)
  * CodeBadge (상태 색상 자동 매핑)
  * MoneyText (천단위 콤마, 음수 빨강, 부호 옵션)
  * PermissionButton (권한 없으면 미렌더)
  * SearchForm (조건 배열 → 자동 폼)
  * ExcelExportButton (blob 다운로드)
  * PageContainer
- 훅: useCommonCodes, usePermission (메뉴별 boolean)
- API 모듈: agent, contract, ledger, settle, code
- 페이지: AgentList, ContractList, RecruitLedger, SettleList
  * SettleList: 월 요약 카드 + 확정/보류 액션 + 권한 체크
- 라우터: /org/agents, /contracts, /ledger/recruit, /settle

V16 fix:
- PAYMENT 메뉴는 V12 에서 level1 directory 로 생성됨 → V16 에서 PAGE 로 UPDATE 후 권한 매트릭스 적용 (자식으로 또 만들면 unique 충돌)
This commit is contained in:
GA Pro
2026-05-09 22:38:10 +09:00
parent d4433a8e46
commit 98eb231950
28 changed files with 1165 additions and 39 deletions
@@ -24,4 +24,6 @@ public interface MaintainLedgerMapper {
int deleteBySettleMonth(@Param("settleMonth") String settleMonth);
List<Map<String, Object>> aggregateByAgent(@Param("settleMonth") String settleMonth);
BigDecimal sumByMonth(@Param("settleMonth") String settleMonth);
BigDecimal sumByAgentMonth(@Param("agentId") Long agentId,
@Param("settleMonth") String settleMonth);
}
@@ -27,4 +27,7 @@ public interface RecruitLedgerMapper {
List<Map<String, Object>> aggregateByAgent(@Param("settleMonth") String settleMonth);
/** 정산월 합계 */
BigDecimal sumByMonth(@Param("settleMonth") String settleMonth);
/** 정산월 + 설계사 합계 */
BigDecimal sumByAgentMonth(@Param("agentId") Long agentId,
@Param("settleMonth") String settleMonth);
}
@@ -16,6 +16,8 @@ public interface OrganizationMapper {
OrganizationVO selectById(@Param("orgId") Long orgId);
/** 자기 자신 + 모든 하위 조직 ID (CTE 재귀) */
List<Long> selectDescendantIds(@Param("orgId") Long orgId);
/** 자기 자신 + 모든 상위 조직 ID (root 까지, 가까운 순) */
List<Long> selectAncestorIds(@Param("orgId") Long orgId);
int insert(OrganizationVO vo);
int update(OrganizationVO vo);
int deleteById(@Param("orgId") Long orgId);
@@ -107,4 +107,9 @@
SELECT COALESCE(SUM(agent_amount), 0) FROM maintain_ledger WHERE settle_month = #{settleMonth}
</select>
<select id="sumByAgentMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(agent_amount), 0) FROM maintain_ledger
WHERE agent_id = #{agentId} AND settle_month = #{settleMonth}
</select>
</mapper>
@@ -124,4 +124,9 @@
SELECT COALESCE(SUM(agent_amount), 0) FROM recruit_ledger WHERE settle_month = #{settleMonth}
</select>
<select id="sumByAgentMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(agent_amount), 0) FROM recruit_ledger
WHERE agent_id = #{agentId} AND settle_month = #{settleMonth}
</select>
</mapper>
@@ -49,6 +49,17 @@
SELECT org_id FROM descendants
</select>
<!-- 자기 자신 + 모든 상위 조직 (가까운 순) -->
<select id="selectAncestorIds" resultType="long">
WITH RECURSIVE ancestors AS (
SELECT org_id, parent_org_id, 0 AS depth FROM organization WHERE org_id = #{orgId}
UNION ALL
SELECT o.org_id, o.parent_org_id, a.depth + 1
FROM organization o JOIN ancestors a ON a.parent_org_id = o.org_id
)
SELECT org_id FROM ancestors ORDER BY depth
</select>
<insert id="insert" parameterType="com.ga.core.vo.org.OrganizationVO" useGeneratedKeys="true" keyProperty="orgId">
INSERT INTO organization (parent_org_id, org_name, org_type, org_level, region,
effective_from, effective_to, is_active, created_at, created_by)