This commit is contained in:
@@ -15,7 +15,7 @@ public class DashboardController {
|
||||
|
||||
private final DashboardService dashboardService;
|
||||
|
||||
// ═══ 대시보드 CRUD ═══
|
||||
// ═══ 대시보드 CRUD (MENU_INFO 단일 본체) ═══
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> getDashboardList(
|
||||
@@ -33,11 +33,11 @@ public class DashboardController {
|
||||
return ResponseEntity.ok(ApiResponse.success(dashboardService.getDashboardList(params)));
|
||||
}
|
||||
|
||||
@GetMapping("/{dashboardId}")
|
||||
@GetMapping("/{objid}")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> getDashboardInfo(
|
||||
@PathVariable String dashboardId) {
|
||||
@PathVariable String objid) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("dashboard_id", dashboardId);
|
||||
params.put("objid", objid);
|
||||
Map<String, Object> result = dashboardService.getDashboardInfo(params);
|
||||
if (result == null) {
|
||||
return ResponseEntity.ok(ApiResponse.error("대시보드를 찾을 수 없습니다"));
|
||||
@@ -55,23 +55,23 @@ public class DashboardController {
|
||||
return ResponseEntity.ok(ApiResponse.success(dashboardService.insertDashboard(body)));
|
||||
}
|
||||
|
||||
@PutMapping("/{dashboardId}")
|
||||
@PutMapping("/{objid}")
|
||||
public ResponseEntity<ApiResponse<Void>> updateDashboard(
|
||||
@PathVariable String dashboardId,
|
||||
@PathVariable String objid,
|
||||
@RequestAttribute("user_id") String userId,
|
||||
@RequestBody Map<String, Object> body) {
|
||||
body.put("dashboard_id", dashboardId);
|
||||
body.put("objid", objid);
|
||||
body.put("user_id", userId);
|
||||
dashboardService.updateDashboard(body);
|
||||
return ResponseEntity.ok(ApiResponse.success(null, "수정 완료"));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{dashboardId}")
|
||||
@DeleteMapping("/{objid}")
|
||||
public ResponseEntity<ApiResponse<Void>> deleteDashboard(
|
||||
@PathVariable String dashboardId,
|
||||
@PathVariable String objid,
|
||||
@RequestAttribute("user_id") String userId) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("dashboard_id", dashboardId);
|
||||
params.put("objid", objid);
|
||||
params.put("user_id", userId);
|
||||
dashboardService.deleteDashboard(params);
|
||||
return ResponseEntity.ok(ApiResponse.success(null, "삭제 완료"));
|
||||
@@ -79,36 +79,36 @@ public class DashboardController {
|
||||
|
||||
// ═══ 카드 CRUD ═══
|
||||
|
||||
@GetMapping("/{dashboardId}/cards")
|
||||
@GetMapping("/{objid}/cards")
|
||||
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getDashboardCards(
|
||||
@PathVariable String dashboardId) {
|
||||
@PathVariable String objid) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("dashboard_id", dashboardId);
|
||||
params.put("menu_objid", objid);
|
||||
return ResponseEntity.ok(ApiResponse.success(dashboardService.getDashboardCardList(params)));
|
||||
}
|
||||
|
||||
@PostMapping("/{dashboardId}/cards")
|
||||
@PostMapping("/{objid}/cards")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> insertDashboardCard(
|
||||
@PathVariable String dashboardId,
|
||||
@PathVariable String objid,
|
||||
@RequestBody Map<String, Object> body) {
|
||||
body.put("dashboard_id", dashboardId);
|
||||
body.put("menu_objid", objid);
|
||||
return ResponseEntity.ok(ApiResponse.success(dashboardService.insertDashboardCard(body)));
|
||||
}
|
||||
|
||||
@PutMapping("/{dashboardId}/cards/{cardId}")
|
||||
@PutMapping("/{objid}/cards/{cardId}")
|
||||
public ResponseEntity<ApiResponse<Void>> updateDashboardCard(
|
||||
@PathVariable String dashboardId,
|
||||
@PathVariable String objid,
|
||||
@PathVariable String cardId,
|
||||
@RequestBody Map<String, Object> body) {
|
||||
body.put("dashboard_id", dashboardId);
|
||||
body.put("menu_objid", objid);
|
||||
body.put("card_id", cardId);
|
||||
dashboardService.updateDashboardCard(body);
|
||||
return ResponseEntity.ok(ApiResponse.success(null));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{dashboardId}/cards/{cardId}")
|
||||
@DeleteMapping("/{objid}/cards/{cardId}")
|
||||
public ResponseEntity<ApiResponse<Void>> deleteDashboardCard(
|
||||
@PathVariable String dashboardId,
|
||||
@PathVariable String objid,
|
||||
@PathVariable String cardId) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("card_id", cardId);
|
||||
@@ -116,23 +116,11 @@ public class DashboardController {
|
||||
return ResponseEntity.ok(ApiResponse.success(null));
|
||||
}
|
||||
|
||||
@PutMapping("/{dashboardId}/cards/batch")
|
||||
@PutMapping("/{objid}/cards/batch")
|
||||
public ResponseEntity<ApiResponse<Void>> updateCardPositions(
|
||||
@PathVariable String dashboardId,
|
||||
@PathVariable String objid,
|
||||
@RequestBody Map<String, Object> body) {
|
||||
dashboardService.updateCardPositions(body);
|
||||
return ResponseEntity.ok(ApiResponse.success(null, "일괄 업데이트 완료"));
|
||||
}
|
||||
|
||||
// ═══ 사이드바 메뉴 ═══
|
||||
|
||||
@GetMapping("/sidebar/menu")
|
||||
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getSidebarMenu(
|
||||
@RequestAttribute("company_code") String companyCode,
|
||||
@RequestAttribute("user_id") String userId) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("company_code", companyCode);
|
||||
params.put("user_id", userId);
|
||||
return ResponseEntity.ok(ApiResponse.success(dashboardService.getSidebarMenu(params)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class DashboardService extends BaseService {
|
||||
|
||||
private static final String NS = "dashboard.";
|
||||
|
||||
// ═══ 대시보드 CRUD ═══
|
||||
// ═══ 대시보드 CRUD (MENU_INFO 단일 본체) ═══
|
||||
|
||||
public Map<String, Object> getDashboardList(Map<String, Object> params) {
|
||||
commonService.applyPagination(params);
|
||||
@@ -32,17 +32,32 @@ public class DashboardService extends BaseService {
|
||||
|
||||
@Transactional
|
||||
public Map<String, Object> insertDashboard(Map<String, Object> params) {
|
||||
String dashboardId = "dash_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12);
|
||||
params.put("dashboard_id", dashboardId);
|
||||
if (params.get("icon") == null) {
|
||||
params.put("icon", "\uD83D\uDCCB");
|
||||
}
|
||||
if (params.get("display_order") == null) {
|
||||
params.put("display_order", 0);
|
||||
String objid = String.valueOf(System.currentTimeMillis());
|
||||
params.put("objid", objid);
|
||||
params.put("writer", params.get("user_id"));
|
||||
|
||||
// 개인 대시보드 여부: is_personal=true 이면 USER_ID 채움, 아니면 NULL (회사 공용)
|
||||
Object isPersonal = params.get("is_personal");
|
||||
boolean personal = isPersonal != null
|
||||
&& (Boolean.TRUE.equals(isPersonal) || "true".equalsIgnoreCase(String.valueOf(isPersonal)));
|
||||
if (!personal) {
|
||||
params.put("user_id", null);
|
||||
}
|
||||
|
||||
// 회사별 자동 시퀀스 = URL. COMPANY_CODE 내 /숫자 형 URL 중 최대값 + 1
|
||||
Integer nextSeq = sqlSession.selectOne(NS + "getNextMenuSeq", params);
|
||||
if (nextSeq == null) nextSeq = 1;
|
||||
String menuUrl = "/" + nextSeq;
|
||||
params.put("seq", String.valueOf(nextSeq));
|
||||
params.put("menu_url", menuUrl);
|
||||
|
||||
sqlSession.insert(NS + "insertDashboard", params);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("dashboard_id", dashboardId);
|
||||
result.put("objid", objid);
|
||||
result.put("dashboard_id", objid); // 프론트 하위호환
|
||||
result.put("menu_url", menuUrl);
|
||||
result.put("seq", nextSeq);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -97,10 +112,4 @@ public class DashboardService extends BaseService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ═══ 사이드바 메뉴 ═══
|
||||
|
||||
public List<Map<String, Object>> getSidebarMenu(Map<String, Object> params) {
|
||||
return sqlSession.selectList(NS + "getSidebarMenu", params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,6 +333,7 @@
|
||||
, LANG_KEY
|
||||
, LANG_KEY_DESC
|
||||
, MENU_ICON
|
||||
, USER_ID
|
||||
) VALUES (
|
||||
#{objid}
|
||||
, #{menu_type}
|
||||
@@ -348,6 +349,7 @@
|
||||
, #{lang_key}
|
||||
, #{lang_key_desc}
|
||||
, #{menu_icon}
|
||||
, #{user_id}
|
||||
)
|
||||
</insert>
|
||||
|
||||
@@ -382,6 +384,7 @@
|
||||
WHERE OBJID = #{menu_id}
|
||||
</update>
|
||||
|
||||
|
||||
<!-- ================================================================
|
||||
사용자 관리
|
||||
================================================================ -->
|
||||
|
||||
@@ -2,117 +2,134 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="dashboard">
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════
|
||||
대시보드 = 사용자 메뉴 (MENU_INFO 단일 본체)
|
||||
- MENU_TYPE='1' AND MENU_URL ~ '^/\d+$' (회사별 시퀀스 숫자 URL) 인 row 가 대시보드
|
||||
- 개인 대시보드: USER_ID = 로그인 사용자
|
||||
- 공용 대시보드: USER_ID IS NULL (같은 COMPANY_CODE 공유)
|
||||
═══════════════════════════════════════════════════════════════ -->
|
||||
|
||||
<!-- ═══ 대시보드 CRUD ═══ -->
|
||||
|
||||
<select id="getDashboardList" parameterType="map" resultType="map">
|
||||
SELECT DASHBOARD_ID
|
||||
, NAME
|
||||
, ICON
|
||||
, DISPLAY_ORDER
|
||||
SELECT OBJID
|
||||
, OBJID AS DASHBOARD_ID
|
||||
, MENU_NAME_KOR AS NAME
|
||||
, MENU_URL
|
||||
, MENU_ICON AS ICON
|
||||
, SEQ AS DISPLAY_ORDER
|
||||
, COMPANY_CODE
|
||||
, USER_ID
|
||||
, IS_ACTIVE
|
||||
, CREATED_BY
|
||||
, STATUS
|
||||
, WRITER AS CREATED_BY
|
||||
, CREATED_DATE
|
||||
, UPDATED_BY
|
||||
, UPDATED_DATE
|
||||
FROM DASHBOARDS
|
||||
WHERE IS_ACTIVE = 'Y'
|
||||
FROM MENU_INFO
|
||||
WHERE MENU_TYPE = '1'
|
||||
AND MENU_URL ~ '^/\d+$'
|
||||
AND STATUS = 'active'
|
||||
<include refid="common.companyCodeFilter"/>
|
||||
AND (USER_ID = #{user_id} OR USER_ID IS NULL)
|
||||
<if test='keyword != null and keyword != ""'>
|
||||
AND NAME LIKE CONCAT('%', #{keyword}, '%')
|
||||
AND MENU_NAME_KOR LIKE CONCAT('%', #{keyword}, '%')
|
||||
</if>
|
||||
ORDER BY DISPLAY_ORDER ASC, CREATED_DATE ASC
|
||||
ORDER BY CAST(COALESCE(NULLIF(SEQ, ''), '0') AS INTEGER) ASC, CREATED_DATE ASC
|
||||
<include refid="common.pagination"/>
|
||||
</select>
|
||||
|
||||
<select id="getDashboardListCnt" parameterType="map" resultType="int">
|
||||
SELECT COUNT(*)
|
||||
FROM DASHBOARDS
|
||||
WHERE IS_ACTIVE = 'Y'
|
||||
FROM MENU_INFO
|
||||
WHERE MENU_TYPE = '1'
|
||||
AND MENU_URL ~ '^/\d+$'
|
||||
AND STATUS = 'active'
|
||||
<include refid="common.companyCodeFilter"/>
|
||||
AND (USER_ID = #{user_id} OR USER_ID IS NULL)
|
||||
<if test='keyword != null and keyword != ""'>
|
||||
AND NAME LIKE CONCAT('%', #{keyword}, '%')
|
||||
AND MENU_NAME_KOR LIKE CONCAT('%', #{keyword}, '%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getDashboardInfo" parameterType="map" resultType="map">
|
||||
SELECT DASHBOARD_ID
|
||||
, NAME
|
||||
, ICON
|
||||
, DISPLAY_ORDER
|
||||
SELECT OBJID
|
||||
, OBJID AS DASHBOARD_ID
|
||||
, MENU_NAME_KOR AS NAME
|
||||
, MENU_URL
|
||||
, MENU_ICON AS ICON
|
||||
, SEQ AS DISPLAY_ORDER
|
||||
, COMPANY_CODE
|
||||
, USER_ID
|
||||
, IS_ACTIVE
|
||||
, CREATED_BY
|
||||
, STATUS
|
||||
, WRITER AS CREATED_BY
|
||||
, CREATED_DATE
|
||||
, UPDATED_BY
|
||||
, UPDATED_DATE
|
||||
FROM DASHBOARDS
|
||||
WHERE DASHBOARD_ID = #{dashboard_id}
|
||||
AND IS_ACTIVE = 'Y'
|
||||
FROM MENU_INFO
|
||||
WHERE OBJID = #{objid}
|
||||
AND MENU_TYPE = '1'
|
||||
AND STATUS = 'active'
|
||||
</select>
|
||||
|
||||
<!-- 회사별 다음 메뉴 시퀀스 (URL 식별자로 사용) -->
|
||||
<select id="getNextMenuSeq" parameterType="map" resultType="int">
|
||||
SELECT COALESCE(MAX(CAST(NULLIF(SEQ, '') AS INTEGER)), 0) + 1
|
||||
FROM MENU_INFO
|
||||
WHERE MENU_TYPE = '1'
|
||||
AND COMPANY_CODE = #{company_code}
|
||||
AND MENU_URL ~ '^/\d+$'
|
||||
</select>
|
||||
|
||||
<insert id="insertDashboard" parameterType="map">
|
||||
INSERT INTO DASHBOARDS (
|
||||
DASHBOARD_ID
|
||||
, NAME
|
||||
, ICON
|
||||
, DISPLAY_ORDER
|
||||
, COMPANY_CODE
|
||||
, USER_ID
|
||||
, IS_ACTIVE
|
||||
, CREATED_BY
|
||||
INSERT INTO MENU_INFO (
|
||||
OBJID
|
||||
, MENU_TYPE
|
||||
, PARENT_OBJ_ID
|
||||
, MENU_NAME_KOR
|
||||
, MENU_URL
|
||||
, SEQ
|
||||
, WRITER
|
||||
, CREATED_DATE
|
||||
, UPDATED_BY
|
||||
, UPDATED_DATE
|
||||
, STATUS
|
||||
, COMPANY_CODE
|
||||
, MENU_ICON
|
||||
, USER_ID
|
||||
) VALUES (
|
||||
#{dashboard_id}
|
||||
#{objid}
|
||||
, '1'
|
||||
, '0'
|
||||
, #{name}
|
||||
, #{icon}
|
||||
, #{display_order}
|
||||
, #{menu_url}
|
||||
, #{seq}
|
||||
, #{writer}
|
||||
, NOW()
|
||||
, 'active'
|
||||
, #{company_code}
|
||||
, COALESCE(#{icon}, '📋')
|
||||
, #{user_id}
|
||||
, 'Y'
|
||||
, #{user_id}
|
||||
, CURRENT_TIMESTAMP
|
||||
, #{user_id}
|
||||
, CURRENT_TIMESTAMP
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updateDashboard" parameterType="map">
|
||||
UPDATE DASHBOARDS
|
||||
SET UPDATED_DATE = CURRENT_TIMESTAMP
|
||||
, UPDATED_BY = #{user_id}
|
||||
<if test='name != null'>
|
||||
, NAME = #{name}
|
||||
</if>
|
||||
<if test='icon != null'>
|
||||
, ICON = #{icon}
|
||||
</if>
|
||||
<if test='display_order != null'>
|
||||
, DISPLAY_ORDER = #{display_order}
|
||||
</if>
|
||||
WHERE DASHBOARD_ID = #{dashboard_id}
|
||||
AND IS_ACTIVE = 'Y'
|
||||
UPDATE MENU_INFO
|
||||
SET
|
||||
<if test='name != null'>MENU_NAME_KOR = #{name},</if>
|
||||
<if test='icon != null'>MENU_ICON = #{icon},</if>
|
||||
<if test='display_order != null'>SEQ = #{display_order},</if>
|
||||
OBJID = OBJID
|
||||
WHERE OBJID = #{objid}
|
||||
AND MENU_TYPE = '1'
|
||||
</update>
|
||||
|
||||
<update id="deleteDashboard" parameterType="map">
|
||||
UPDATE DASHBOARDS
|
||||
SET IS_ACTIVE = 'D'
|
||||
, UPDATED_DATE = CURRENT_TIMESTAMP
|
||||
, UPDATED_BY = #{user_id}
|
||||
WHERE DASHBOARD_ID = #{dashboard_id}
|
||||
UPDATE MENU_INFO
|
||||
SET STATUS = 'inactive'
|
||||
WHERE OBJID = #{objid}
|
||||
AND MENU_TYPE = '1'
|
||||
</update>
|
||||
|
||||
<!-- ═══ 대시보드 카드 ═══ -->
|
||||
|
||||
<select id="getDashboardCardList" parameterType="map" resultType="map">
|
||||
SELECT DC.CARD_ID
|
||||
, DC.DASHBOARD_ID
|
||||
, DC.MENU_OBJID
|
||||
, DC.MENU_OBJID AS DASHBOARD_ID
|
||||
, DC.TEMPLATE_ID
|
||||
, DC.POSITION_X
|
||||
, DC.POSITION_Y
|
||||
@@ -130,15 +147,15 @@
|
||||
, T.STATUS AS TEMPLATE_STATUS
|
||||
FROM DASHBOARD_CARDS DC
|
||||
LEFT JOIN TEMPLATES T ON DC.TEMPLATE_ID = T.TEMPLATE_ID AND T.IS_ACTIVE = 'Y'
|
||||
WHERE DC.DASHBOARD_ID = #{dashboard_id}
|
||||
AND DC.IS_ACTIVE = 'Y'
|
||||
WHERE DC.MENU_OBJID = #{menu_objid}
|
||||
AND DC.IS_ACTIVE = 'Y'
|
||||
ORDER BY DC.DISPLAY_ORDER ASC, DC.CREATED_DATE ASC
|
||||
</select>
|
||||
|
||||
<insert id="insertDashboardCard" parameterType="map">
|
||||
INSERT INTO DASHBOARD_CARDS (
|
||||
CARD_ID
|
||||
, DASHBOARD_ID
|
||||
, MENU_OBJID
|
||||
, TEMPLATE_ID
|
||||
, POSITION_X
|
||||
, POSITION_Y
|
||||
@@ -151,7 +168,7 @@
|
||||
, UPDATED_DATE
|
||||
) VALUES (
|
||||
#{card_id}
|
||||
, #{dashboard_id}
|
||||
, #{menu_objid}
|
||||
, #{template_id}
|
||||
, #{position_x}
|
||||
, #{position_y}
|
||||
@@ -187,7 +204,7 @@
|
||||
, DISPLAY_ORDER = #{display_order}
|
||||
</if>
|
||||
WHERE CARD_ID = #{card_id}
|
||||
AND IS_ACTIVE = 'Y'
|
||||
AND IS_ACTIVE = 'Y'
|
||||
</update>
|
||||
|
||||
<update id="updateCardPosition" parameterType="map">
|
||||
@@ -199,7 +216,7 @@
|
||||
, IS_COLLAPSED = #{is_collapsed}
|
||||
, UPDATED_DATE = CURRENT_TIMESTAMP
|
||||
WHERE CARD_ID = #{card_id}
|
||||
AND IS_ACTIVE = 'Y'
|
||||
AND IS_ACTIVE = 'Y'
|
||||
</update>
|
||||
|
||||
<update id="deleteDashboardCard" parameterType="map">
|
||||
@@ -209,18 +226,4 @@
|
||||
WHERE CARD_ID = #{card_id}
|
||||
</update>
|
||||
|
||||
<!-- ═══ 사이드바 메뉴 ═══ -->
|
||||
|
||||
<select id="getSidebarMenu" parameterType="map" resultType="map">
|
||||
SELECT DASHBOARD_ID
|
||||
, NAME
|
||||
, ICON
|
||||
, DISPLAY_ORDER
|
||||
FROM DASHBOARDS
|
||||
WHERE IS_ACTIVE = 'Y'
|
||||
<include refid="common.companyCodeFilter"/>
|
||||
AND (USER_ID = #{user_id} OR USER_ID IS NULL)
|
||||
ORDER BY DISPLAY_ORDER ASC, CREATED_DATE ASC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user