대시보드, 기기에러, 계정관리 수정
This commit is contained in:
@@ -195,6 +195,8 @@ public class _AG {
|
||||
uri.compareTo("/api/terminal-state.do") == 0 ||
|
||||
uri.compareTo("/api/sign-in.do") == 0 ||
|
||||
uri.compareTo("/api/sval2.do") == 0 ||
|
||||
uri.compareTo("/api/send-sms-test.do") == 0 || //TempCode: SMS integration test, remove when done
|
||||
uri.compareTo("/api/add-device-error.do") == 0 ||
|
||||
uri.compareTo("/api/add-transaction.do") == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
package com.handong.smartservice.component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Decoder for the "자판기 이상 DATA (DC = 0x03)" telegram stored in device_error.error_code.
|
||||
* Spec: 카드리더기_롯데_통신전문_추가사양_할부결제_요청 문서 10.3 (5 ~ 15 byte 가변)
|
||||
*
|
||||
* byte 1 bit0~7 : 대표이상 / 코인메카니즘 / 지폐식별기 / 물없음 / 온수저온 / 얼음품절 / 컵품절·컵걸림 / 배수부 가득참
|
||||
* byte 2 bit0~6 : System 이상 / 기타 이상 / Bucket 이상 / Door Open / 슬레이브 이상 / Reserved / Reserved
|
||||
* byte 3~14 : 품절 컬럼 1 ~ 96 (byte 당 8 컬럼)
|
||||
* byte 15 : 하위니블 = 품절 컬럼 97~99, 상위니블 = 컬럼 백의자리(0~9)
|
||||
*/
|
||||
public class DeviceErrorCode {
|
||||
|
||||
public static final String STATE_FAULT = "이상";
|
||||
public static final String STATE_SOLD_OUT = "품절";
|
||||
|
||||
private static final String[] BYTE1_LABELS = {
|
||||
"대표이상",
|
||||
"코인메카니즘 관련 이상",
|
||||
"지폐식별기 관련 이상",
|
||||
"물없음",
|
||||
"온수저온",
|
||||
"얼음품절",
|
||||
"컵품절 또는 컵걸림",
|
||||
"배수부 가득참",
|
||||
};
|
||||
|
||||
private static final String[] BYTE2_LABELS = {
|
||||
"System 이상",
|
||||
"기타 이상",
|
||||
"Bucket 이상",
|
||||
"Door Open",
|
||||
"슬레이브 이상",
|
||||
"Reserved(14)",
|
||||
"Reserved(15)",
|
||||
};
|
||||
|
||||
private static int[] toBytes(String error_code) {
|
||||
if (error_code == null)
|
||||
return new int[0];
|
||||
|
||||
String hex = error_code.trim();
|
||||
if (hex.length() < 2 || hex.length() % 2 != 0 || hex.matches(".*[^0-9a-fA-F].*"))
|
||||
return new int[0];
|
||||
|
||||
int[] bytes = new int[hex.length() / 2];
|
||||
for (int i = 0; i < bytes.length; i++)
|
||||
bytes[i] = Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/** 대표이상을 제외한 단말기 이상 목록 */
|
||||
public static List<String> getFaults(String error_code) {
|
||||
int[] bytes = toBytes(error_code);
|
||||
List<String> faults = new ArrayList<>();
|
||||
if (bytes.length == 0)
|
||||
return faults;
|
||||
|
||||
for (int bit = 1; bit < 8; bit++) {
|
||||
if ((bytes[0] & (1 << bit)) != 0)
|
||||
faults.add(BYTE1_LABELS[bit]);
|
||||
}
|
||||
|
||||
if (bytes.length >= 2) {
|
||||
for (int bit = 0; bit < 7; bit++) {
|
||||
if ((bytes[1] & (1 << bit)) != 0)
|
||||
faults.add(BYTE2_LABELS[bit]);
|
||||
}
|
||||
}
|
||||
|
||||
return faults;
|
||||
}
|
||||
|
||||
/** 품절 컬럼번호 목록 */
|
||||
public static List<Integer> getSoldOutColumns(String error_code) {
|
||||
int[] bytes = toBytes(error_code);
|
||||
List<Integer> columns = new ArrayList<>();
|
||||
if (bytes.length == 0)
|
||||
return columns;
|
||||
|
||||
// The last byte carries the hundreds digit of the column number in its upper nibble
|
||||
int hundreds = bytes.length >= 15 ? (bytes[14] >> 4) & 0x0f : 0;
|
||||
int base = hundreds * 100;
|
||||
|
||||
int last = Math.min(bytes.length, 14);
|
||||
for (int index = 2; index < last; index++) {
|
||||
for (int bit = 0; bit < 8; bit++) {
|
||||
if ((bytes[index] & (1 << bit)) != 0)
|
||||
columns.add(base + (index - 2) * 8 + bit + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes.length >= 15) {
|
||||
for (int bit = 0; bit < 3; bit++) {
|
||||
if ((bytes[14] & (1 << bit)) != 0)
|
||||
columns.add(base + 97 + bit);
|
||||
}
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
public static boolean hasRepresentative(String error_code) {
|
||||
int[] bytes = toBytes(error_code);
|
||||
return bytes.length > 0 && (bytes[0] & 0x01) != 0;
|
||||
}
|
||||
|
||||
/** One line summary of the telegram, shown in the list screen. */
|
||||
public static String describe(String error_code) {
|
||||
List<String> parts = new ArrayList<>(getFaults(error_code));
|
||||
List<Integer> columns = getSoldOutColumns(error_code);
|
||||
|
||||
if (columns.size() > 0) {
|
||||
StringBuilder sb = new StringBuilder("품절 (컬럼 ");
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0)
|
||||
sb.append(", ");
|
||||
sb.append(columns.get(i));
|
||||
}
|
||||
sb.append(")");
|
||||
parts.add(sb.toString());
|
||||
}
|
||||
|
||||
if (parts.isEmpty())
|
||||
return hasRepresentative(error_code) ? "대표이상" : "";
|
||||
|
||||
return String.join(", ", parts);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -24,8 +24,8 @@ public class SMSSender {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SMSSender.class);
|
||||
|
||||
// Munja114 account, issued and authorized through the Munja114 customer center
|
||||
private static final String REMOTE_ID = "";
|
||||
private static final String REMOTE_PASS = "";
|
||||
private static final String REMOTE_ID = "handong3883";
|
||||
private static final String REMOTE_PASS = "gksehd3885@";
|
||||
|
||||
private static final String URL_SMS = "https://www.munja114.co.kr/Remote/RemoteSms.html";
|
||||
private static final String URL_LMS = "https://www.munja114.co.kr/Remote/RemoteMms.html";
|
||||
|
||||
+2
-1
@@ -56,8 +56,9 @@ class AccountController {
|
||||
String user_id = body.get("user_id");
|
||||
String email = body.get("email");
|
||||
Long biz_group_id = _AG.toLong(body.get("biz_group_id"));
|
||||
Long state = _AG.toLong(body.get("state"));
|
||||
|
||||
Map<String, Object> mapResult = accountService.getAccountList(offset, limit, date_start, date_end, is_excel, is_group_access, user_id, email, name, phone, biz_group_id);
|
||||
Map<String, Object> mapResult = accountService.getAccountList(offset, limit, date_start, date_end, is_excel, is_group_access, user_id, email, name, phone, biz_group_id, state);
|
||||
|
||||
if (is_excel) {
|
||||
List<Map<String, String>> list = (List<Map<String, String>>)mapResult.get("list");
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.handong.smartservice.controller.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.handong.smartservice._AG;
|
||||
import com.handong.smartservice.component.CtResponse;
|
||||
import com.handong.smartservice.service.DashboardService;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
class DashboardController {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private static final long DEFAULT_DAYS = 7L;
|
||||
private static final long MAX_DAYS = 31L;
|
||||
|
||||
private final DashboardService dashboardService;
|
||||
|
||||
public DashboardController(DashboardService dashboardService) {
|
||||
this.dashboardService = dashboardService;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/get-dashboard.do", method = RequestMethod.POST)
|
||||
public CtResponse getDashboard(HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) Map<String, String> body) {
|
||||
logger.info("req: " + request.getRequestURI());
|
||||
|
||||
CtResponse result = new CtResponse();
|
||||
|
||||
Long days = body != null ? _AG.toLong(body.get("days")) : 0L;
|
||||
if (days == null || days <= 0)
|
||||
days = DEFAULT_DAYS;
|
||||
if (days > MAX_DAYS)
|
||||
days = MAX_DAYS;
|
||||
|
||||
result.put("result", dashboardService.getDashboard(days));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package com.handong.smartservice.controller.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.handong.smartservice._AG;
|
||||
import com.handong.smartservice.component.CtExcelMaker;
|
||||
import com.handong.smartservice.component.CtResponse;
|
||||
import com.handong.smartservice.component.ErrorCode;
|
||||
import com.handong.smartservice.service.DeviceErrorService;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
class DeviceErrorController {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final DeviceErrorService deviceErrorService;
|
||||
|
||||
public DeviceErrorController(DeviceErrorService deviceErrorService) {
|
||||
this.deviceErrorService = deviceErrorService;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/get-device-error.do", method = RequestMethod.POST)
|
||||
public CtResponse getDeviceErrorList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
|
||||
logger.info("req: " + request.getRequestURI());
|
||||
|
||||
CtResponse result = new CtResponse();
|
||||
|
||||
Boolean is_excel = _AG.toBoolean(body.get("is_excel"));
|
||||
Long offset = _AG.toLong(body.get("offset"));
|
||||
Long limit = _AG.toLong(body.get("limit"));
|
||||
if (limit > 100)
|
||||
limit = 100L;
|
||||
|
||||
Boolean is_group_access = _AG.toBoolean(body.get("is_group_access"));
|
||||
String date_start = body.get("date_start");
|
||||
String date_end = body.get("date_end");
|
||||
Long biz_group_id = _AG.toLong(body.get("biz_group_id"));
|
||||
String device_name = body.get("device_name");
|
||||
String uid1 = body.get("uid1");
|
||||
Long uid1_type = _AG.toLong(body.get("uid1_type"));
|
||||
String type = body.get("type");
|
||||
String error_code = body.get("error_code");
|
||||
Long error_type = _AG.toLong(body.get("error_type"));
|
||||
|
||||
Map<String, Object> mapResult = deviceErrorService.getDeviceErrorList(is_excel, offset, limit, is_group_access, biz_group_id, date_start, date_end,
|
||||
device_name, uid1, uid1_type, type, error_code, error_type);
|
||||
|
||||
if (is_excel) {
|
||||
List<Map<String, String>> list = (List<Map<String, String>>)mapResult.get("list");
|
||||
|
||||
for (Map<String, String> item : list) {
|
||||
item.replace("reg_time", _AG.timestampToStr(item.get("reg_time")));
|
||||
}
|
||||
|
||||
// The vending machine type and the raw telegram are kept in the DB only, never shown
|
||||
String[] arrHeader = {"발생시간", "무인기기명", "단말기 TID", "에러유형", "에러내용"};
|
||||
String[] arrColumn = {"reg_time", "device_name", "uid1", "error_type", "error_desc"};
|
||||
|
||||
CtExcelMaker.makeExcelResponse(request, response, "ERROR품절내역목록", arrHeader, arrColumn, list, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
result.put("result", mapResult);
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/get-device-error-detail.do", method = RequestMethod.POST)
|
||||
public CtResponse getDeviceErrorDetail(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
|
||||
logger.info("req: " + request.getRequestURI());
|
||||
|
||||
CtResponse result = new CtResponse();
|
||||
|
||||
Long device_error_id = _AG.toLong(body.get("device_error_id"));
|
||||
if (device_error_id == 0) {
|
||||
result.setErrCode(ErrorCode.INVALID_PARAMETER);
|
||||
return result;
|
||||
}
|
||||
|
||||
result.put("result", deviceErrorService.getDeviceErrorDetail(device_error_id));
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/add-device-error.do", method = RequestMethod.POST)
|
||||
public CtResponse addDeviceError(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, String> body) {
|
||||
logger.info("req: " + request.getRequestURI());
|
||||
|
||||
CtResponse result = new CtResponse();
|
||||
|
||||
String uid1 = body.get("uid1");
|
||||
Long uid1_type = _AG.toLong(body.get("uid1_type"));
|
||||
String type = body.get("type");
|
||||
String error_code = body.get("error_code");
|
||||
Long error_type = _AG.toLong(body.get("error_type"));
|
||||
|
||||
if (_AG.hasText(uid1) == false || uid1_type == null || _AG.hasText(type) == false) {
|
||||
result.setErrCode(ErrorCode.INVALID_PARAMETER);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = deviceErrorService.addDeviceError(uid1, uid1_type, type, error_code, error_type);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.handong.smartservice.controller.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.handong.smartservice.component.CtResponse;
|
||||
import com.handong.smartservice.component.SMSSender;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* TEMPORARY: sends one fixed test message so the Munja114 integration can be verified
|
||||
* from the sign in screen. The callback, the receiver and the body are fixed here on
|
||||
* purpose - the endpoint is reachable without a token, so it must not be able to send
|
||||
* an arbitrary message to an arbitrary number. Delete this class once the test is done.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
class SmsTestController {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private static final String TEST_CALLBACK = "0314263883";
|
||||
private static final String TEST_PHONE = "01040334076";
|
||||
private static final String TEST_MESSAGE = "안녕하세요. 테스트입니다.";
|
||||
|
||||
@RequestMapping(value = "/send-sms-test.do", method = RequestMethod.POST)
|
||||
public CtResponse sendSmsTest(HttpServletRequest request) {
|
||||
logger.info("req: " + request.getRequestURI());
|
||||
|
||||
SMSSender.Result sendResult = SMSSender.send(TEST_CALLBACK, TEST_PHONE, TEST_MESSAGE);
|
||||
logger.info("send-sms-test: " + sendResult);
|
||||
|
||||
CtResponse result = new CtResponse();
|
||||
result.put("code", sendResult.code);
|
||||
result.put("msg", sendResult.msg);
|
||||
result.put("sentCount", sendResult.sentCount);
|
||||
result.put("remainCount", sendResult.remainCount);
|
||||
result.put("callback", TEST_CALLBACK);
|
||||
result.put("phone", TEST_PHONE);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -74,8 +74,8 @@ class TransactionController {
|
||||
item.replace("order_time", _AG.timestampToStr(item.get("order_time")));
|
||||
}
|
||||
|
||||
String[] arrHeader = {"거래시간", "단말기 TID", "금액", "결제유형", "승인번호", "컬럼번호", "상품코드", "상품명", "결제서비스업체"};
|
||||
String[] arrColumn = {"order_time", "uid1", "amount", "type", "approval", "column_no", "code", "goods_name", "pay_vendor"};
|
||||
String[] arrHeader = {"거래시간", "단말기 TID", "금액", "결제유형", "승인번호", "카드번호", "컬럼번호", "상품코드", "상품명", "결제서비스업체"};
|
||||
String[] arrColumn = {"order_time", "uid1", "amount", "type", "approval", "card_num", "column_no", "code", "goods_name", "pay_vendor"};
|
||||
|
||||
CtExcelMaker.makeExcelResponse(request, response, "거래내역목록", arrHeader, arrColumn, list, null);
|
||||
return null;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ public interface AccountMapper {
|
||||
String date_start, String date_end, Long gid, String user_id, String email, String name, String phone, Long biz_group_id);
|
||||
|
||||
List<Map<String, Object>> selectAccount2(Boolean isCount, Long offset, Long limit,
|
||||
String date_start, String date_end, Boolean is_excel, Long gid, String user_id, String email, String name, String phone, Long biz_group_id);
|
||||
String date_start, String date_end, Boolean is_excel, Long gid, String user_id, String email, String name, String phone, Long biz_group_id, Long state);
|
||||
|
||||
int insertAccount(Map<String, Object> params);
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.handong.smartservice.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Read only queries for the dashboard, all limited to a short period.
|
||||
* is_all == true means the caller is a super admin and sees every group,
|
||||
* otherwise the rows are limited to biz_group_id and its sub groups.
|
||||
*/
|
||||
@Mapper
|
||||
public interface DashboardMapper {
|
||||
|
||||
List<Map<String, Object>> selectNoticeOfPeriod(String date_start, String date_end);
|
||||
|
||||
List<Map<String, Object>> selectSalesOfPeriod(Boolean is_all, Long biz_group_id, String date_start, String date_end);
|
||||
|
||||
List<Map<String, Object>> selectDeviceErrorOfPeriod(Boolean is_all, Long biz_group_id, String date_start, String date_end);
|
||||
|
||||
List<Map<String, Object>> selectAccountOfPeriod(Boolean is_all, Long biz_group_id, String date_start, String date_end);
|
||||
|
||||
List<Map<String, Object>> selectGoodsOfPeriod(Boolean is_all, Long biz_group_id, String date_start, String date_end);
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.handong.smartservice.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface DeviceErrorMapper {
|
||||
|
||||
List<Map<String, Object>> selectDeviceError(Boolean isCount, Boolean is_excel, Long offset, Long limit, Boolean is_group_access,
|
||||
Long biz_group_id, String date_start, String date_end, String device_name, String uid1, Long uid1_type, String type,
|
||||
String error_code, Long error_type);
|
||||
|
||||
Map<String, Object> selectDeviceErrorById(Long device_error_id);
|
||||
|
||||
int insertDeviceError(Map<String, Object> params);
|
||||
}
|
||||
+4
-4
@@ -54,17 +54,17 @@ public class AccountService {
|
||||
return result;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAccountList(Long offset, Long limit, String date_start, String date_end, Boolean is_excel, Boolean is_group_access, String user_id, String email, String name, String phone, Long biz_group_id) {
|
||||
public Map<String, Object> getAccountList(Long offset, Long limit, String date_start, String date_end, Boolean is_excel, Boolean is_group_access, String user_id, String email, String name, String phone, Long biz_group_id, Long state) {
|
||||
Map<String, Object> mapResult = new HashMap<>();
|
||||
|
||||
//if (is_group_access) {
|
||||
|
||||
List<Map<String, Object>> listMap = (List<Map<String, Object>>)accountMapper.selectAccount2(false, offset, limit,
|
||||
date_start, date_end, is_excel, 0L, user_id, email, name, phone, biz_group_id);
|
||||
date_start, date_end, is_excel, 0L, user_id, email, name, phone, biz_group_id, state);
|
||||
mapResult.put("list", listMap);
|
||||
|
||||
Long totalCount = _AG.getNumberFromQuery("COUNT(*)", accountMapper.selectAccount2(true, offset, limit,
|
||||
date_start, date_end, is_excel, 0L, user_id, email, name, phone, biz_group_id));
|
||||
date_start, date_end, is_excel, 0L, user_id, email, name, phone, biz_group_id, state));
|
||||
mapResult.put("totalCount", totalCount);
|
||||
mapResult.put("offset", offset);
|
||||
return mapResult;
|
||||
@@ -150,7 +150,7 @@ public class AccountService {
|
||||
if (changed == 0) {
|
||||
result.setErrCode(ErrorCode.QUERY_ERROR);
|
||||
}
|
||||
DbLogger.insert(2L, "계정 삭제, id: " + ids, 2L);
|
||||
DbLogger.insert(2L, "계정 해지, id: " + ids, 2L);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.handong.smartservice.service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.handong.smartservice.component.Permission;
|
||||
import com.handong.smartservice.component.UserInfo;
|
||||
import com.handong.smartservice.mapper.DashboardMapper;
|
||||
|
||||
@Service
|
||||
public class DashboardService {
|
||||
|
||||
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
|
||||
private final DashboardMapper dashboardMapper;
|
||||
|
||||
public DashboardService(DashboardMapper dashboardMapper) {
|
||||
this.dashboardMapper = dashboardMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Every widget of the dashboard in one call, limited to the last {@code days} days.
|
||||
* The scope comes from the signed in account, never from the request.
|
||||
*/
|
||||
public Map<String, Object> getDashboard(Long days) {
|
||||
UserInfo userInfo = UserInfo.getCurr();
|
||||
|
||||
Boolean is_all = Permission.PERM_ALL.equals(userInfo.getPermission());
|
||||
Long biz_group_id = userInfo.getBizGroupId();
|
||||
|
||||
LocalDate today = LocalDate.now();
|
||||
String date_end = today.format(DATE_FORMAT);
|
||||
String date_start = today.minusDays(days - 1).format(DATE_FORMAT);
|
||||
|
||||
Map<String, Object> mapResult = new HashMap<>();
|
||||
mapResult.put("date_start", date_start);
|
||||
mapResult.put("date_end", date_end);
|
||||
mapResult.put("notice_list", dashboardMapper.selectNoticeOfPeriod(date_start, date_end));
|
||||
mapResult.put("sales_list", dashboardMapper.selectSalesOfPeriod(is_all, biz_group_id, date_start, date_end));
|
||||
mapResult.put("device_error_list", dashboardMapper.selectDeviceErrorOfPeriod(is_all, biz_group_id, date_start, date_end));
|
||||
mapResult.put("account_list", dashboardMapper.selectAccountOfPeriod(is_all, biz_group_id, date_start, date_end));
|
||||
mapResult.put("goods_list", dashboardMapper.selectGoodsOfPeriod(is_all, biz_group_id, date_start, date_end));
|
||||
|
||||
return mapResult;
|
||||
}
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
package com.handong.smartservice.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.handong.smartservice._AG;
|
||||
import com.handong.smartservice.component.CtResponse;
|
||||
import com.handong.smartservice.component.DeviceErrorCode;
|
||||
import com.handong.smartservice.mapper.BizGroupMapper;
|
||||
import com.handong.smartservice.mapper.DeviceErrorMapper;
|
||||
import com.handong.smartservice.mapper.GoodsMapper;
|
||||
import com.handong.smartservice.mapper.TerminalMapper;
|
||||
|
||||
@Service
|
||||
public class DeviceErrorService {
|
||||
|
||||
private final DeviceErrorMapper deviceErrorMapper;
|
||||
private final GoodsMapper goodsMapper;
|
||||
private final BizGroupMapper bizGroupMapper;
|
||||
private final TerminalMapper terminalMapper;
|
||||
|
||||
public DeviceErrorService(DeviceErrorMapper deviceErrorMapper, GoodsMapper goodsMapper, BizGroupMapper bizGroupMapper, TerminalMapper terminalMapper) {
|
||||
this.deviceErrorMapper = deviceErrorMapper;
|
||||
this.goodsMapper = goodsMapper;
|
||||
this.bizGroupMapper = bizGroupMapper;
|
||||
this.terminalMapper = terminalMapper;
|
||||
}
|
||||
|
||||
public Map<String, Object> getDeviceErrorList(Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id,
|
||||
String date_start, String date_end, String device_name, String uid1, Long uid1_type, String type,
|
||||
String error_code, Long error_type) {
|
||||
Map<String, Object> mapResult = new HashMap<>();
|
||||
|
||||
List<Map<String, Object>> listMap = (List<Map<String, Object>>)deviceErrorMapper.selectDeviceError(false, is_excel, offset, limit, is_group_access,
|
||||
biz_group_id, date_start, date_end, device_name, uid1, uid1_type, type, error_code, error_type);
|
||||
|
||||
// The telegram is kept in the DB only, so the readable summary is built here
|
||||
for (Map<String, Object> item : listMap)
|
||||
item.put("error_desc", DeviceErrorCode.describe((String)item.get("error_code")));
|
||||
|
||||
mapResult.put("list", listMap);
|
||||
|
||||
Long totalCount = _AG.getNumberFromQuery("COUNT(*)", deviceErrorMapper.selectDeviceError(true, is_excel, offset, limit, is_group_access,
|
||||
biz_group_id, date_start, date_end, device_name, uid1, uid1_type, type, error_code, error_type));
|
||||
mapResult.put("totalCount", totalCount);
|
||||
mapResult.put("offset", offset);
|
||||
return mapResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the telegram of one record into a line per fault / sold out column,
|
||||
* and names the goods that are registered on each sold out column.
|
||||
*/
|
||||
public Map<String, Object> getDeviceErrorDetail(Long device_error_id) {
|
||||
Map<String, Object> mapResult = new HashMap<>();
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
|
||||
Map<String, Object> mapError = deviceErrorMapper.selectDeviceErrorById(device_error_id);
|
||||
if (mapError == null) {
|
||||
mapResult.put("list", list);
|
||||
return mapResult;
|
||||
}
|
||||
|
||||
String error_code = (String)mapError.get("error_code");
|
||||
|
||||
for (String fault : DeviceErrorCode.getFaults(error_code)) {
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("detail", fault);
|
||||
item.put("goods_code", null);
|
||||
item.put("goods_name", null);
|
||||
item.put("state", DeviceErrorCode.STATE_FAULT);
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
List<Integer> columns = DeviceErrorCode.getSoldOutColumns(error_code);
|
||||
if (columns.size() > 0) {
|
||||
Map<Long, Map<String, Object>> mapGoods = getGoodsByColumn(toLong(mapError.get("device_id")));
|
||||
|
||||
for (Integer column : columns) {
|
||||
Map<String, Object> goods = mapGoods.get(column.longValue());
|
||||
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("detail", column + "번 컬럼 품절");
|
||||
item.put("goods_code", goods != null ? goods.get("code") : null);
|
||||
item.put("goods_name", goods != null ? goods.get("name") : null);
|
||||
item.put("state", DeviceErrorCode.STATE_SOLD_OUT);
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
mapResult.put("result_info", mapError);
|
||||
mapResult.put("list", list);
|
||||
return mapResult;
|
||||
}
|
||||
|
||||
// device_goods keeps the column number as text ("01", "02", ...), so it is normalized to a number
|
||||
private Map<Long, Map<String, Object>> getGoodsByColumn(Long device_id) {
|
||||
Map<Long, Map<String, Object>> mapGoods = new HashMap<>();
|
||||
if (device_id == 0)
|
||||
return mapGoods;
|
||||
|
||||
List<Map<String, Object>> listGoods = goodsMapper.selectDeviceGoods(device_id, null, null);
|
||||
if (listGoods == null)
|
||||
return mapGoods;
|
||||
|
||||
for (Map<String, Object> goods : listGoods)
|
||||
mapGoods.put(_AG.toLong((String)goods.get("column_no")), goods);
|
||||
|
||||
return mapGoods;
|
||||
}
|
||||
|
||||
private Long toLong(Object obj) {
|
||||
return obj instanceof Number ? ((Number)obj).longValue() : 0L;
|
||||
}
|
||||
|
||||
public CtResponse addDeviceError(String uid1, Long uid1_type, String type, String error_code, Long error_type) {
|
||||
CtResponse result = new CtResponse();
|
||||
Long biz_group_id = 0L;
|
||||
Long device_id = 0L;
|
||||
|
||||
// The kiosk only knows its own TID, so the group and the device are resolved from it
|
||||
Map<String, Object> terminal = terminalMapper.selectTerminal3(uid1, uid1_type);
|
||||
if (terminal != null) {
|
||||
device_id = (Long)terminal.get("device_id");
|
||||
Map<String, Object> mapBizGroup = bizGroupMapper.selectBizGroupByDeviceId(device_id);
|
||||
if (mapBizGroup != null) {
|
||||
biz_group_id = (Long)mapBizGroup.get("biz_group_id");
|
||||
}
|
||||
else {
|
||||
Long terminal_id = (Long)terminal.get("terminal_id");
|
||||
Map<String, Object> mapBizGroup2 = bizGroupMapper.selectBizGroupByTerminalId(terminal_id);
|
||||
if (mapBizGroup2 != null) {
|
||||
biz_group_id = (Long)mapBizGroup2.get("biz_group_id");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("uid1", uid1);
|
||||
params.put("uid1_type", uid1_type);
|
||||
params.put("type", type);
|
||||
params.put("error_code", error_code);
|
||||
params.put("error_type", error_type);
|
||||
params.put("biz_group_id", biz_group_id);
|
||||
params.put("device_id", device_id);
|
||||
|
||||
deviceErrorMapper.insertDeviceError(params);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,10 @@
|
||||
</choose>
|
||||
FROM account AS AC
|
||||
JOIN group_tree GT ON GT.biz_group_id = AC.biz_group_id
|
||||
WHERE state != 2
|
||||
WHERE 1 = 1
|
||||
<if test='state != null and state != 0'>
|
||||
AND AC.state = #{state}
|
||||
</if>
|
||||
<if test='date_start != null and date_start != ""'>
|
||||
AND #{date_start} <= DATE(AC.reg_time)
|
||||
</if>
|
||||
@@ -96,7 +99,8 @@
|
||||
AND AC.phone like CONCAT(#{phone}, '%')
|
||||
</if>
|
||||
<if test='isCount == false and is_excel == false'>
|
||||
ORDER BY gid DESC LIMIT #{limit} OFFSET #{offset}
|
||||
/* the terminated accounts always go last */
|
||||
ORDER BY (AC.state = 2), AC.gid DESC LIMIT #{limit} OFFSET #{offset}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.handong.smartservice.mapper.DashboardMapper">
|
||||
|
||||
<sql id="targetGroupCte">
|
||||
<if test='is_all == false'>
|
||||
WITH target_group AS (
|
||||
WITH RECURSIVE group_tree AS (
|
||||
SELECT
|
||||
BG1.biz_group_id,
|
||||
1 AS depth
|
||||
FROM biz_group BG1
|
||||
WHERE BG1.state != 2 AND BG1.biz_group_id = #{biz_group_id}
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
BG2.biz_group_id,
|
||||
GT.depth + 1
|
||||
FROM biz_group BG2
|
||||
INNER JOIN group_tree GT ON BG2.pid = GT.biz_group_id
|
||||
WHERE BG2.state != 2 AND GT.depth < 10
|
||||
)
|
||||
SELECT biz_group_id
|
||||
FROM group_tree
|
||||
)
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="selectNoticeOfPeriod" resultType="map">
|
||||
SELECT N.notice_id, N.reg_time, N.title
|
||||
FROM notice AS N
|
||||
WHERE N.state != 2
|
||||
AND #{date_start} <= DATE(N.reg_time) AND DATE(N.reg_time) <= #{date_end}
|
||||
ORDER BY N.reg_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectSalesOfPeriod" resultType="map">
|
||||
<include refid="targetGroupCte" />
|
||||
SELECT
|
||||
DATE_FORMAT(T.reg_time, '%Y-%m-%d') AS date,
|
||||
COUNT(*) AS total_count,
|
||||
SUM(CASE WHEN T.type IN ('D1','I1','B1','TM1','EB1') THEN 1 ELSE 0 END) AS approval_count,
|
||||
SUM(CASE WHEN T.type IN ('D4','I4','B4','TM4','EB4') THEN 1 ELSE 0 END) AS cancel_count,
|
||||
SUM(T.amount) AS total_amount
|
||||
FROM transactions AS T
|
||||
WHERE #{date_start} <= DATE(T.reg_time) AND DATE(T.reg_time) <= #{date_end}
|
||||
<if test='is_all == false'>
|
||||
AND T.biz_group_id IN ( SELECT biz_group_id FROM target_group )
|
||||
</if>
|
||||
GROUP BY DATE_FORMAT(T.reg_time, '%Y-%m-%d')
|
||||
ORDER BY date DESC
|
||||
</select>
|
||||
|
||||
<select id="selectDeviceErrorOfPeriod" resultType="map">
|
||||
<include refid="targetGroupCte" />
|
||||
SELECT
|
||||
DATE_FORMAT(E.reg_time, '%Y-%m-%d') AS date,
|
||||
SUM(CASE WHEN E.error_type = 1 THEN 1 ELSE 0 END) AS fault_count,
|
||||
SUM(CASE WHEN E.error_type = 2 THEN 1 ELSE 0 END) AS sold_out_count,
|
||||
COUNT(*) AS total_count
|
||||
FROM device_error AS E
|
||||
WHERE #{date_start} <= DATE(E.reg_time) AND DATE(E.reg_time) <= #{date_end}
|
||||
<if test='is_all == false'>
|
||||
AND E.biz_group_id IN ( SELECT biz_group_id FROM target_group )
|
||||
</if>
|
||||
GROUP BY DATE_FORMAT(E.reg_time, '%Y-%m-%d')
|
||||
ORDER BY date DESC
|
||||
</select>
|
||||
|
||||
<select id="selectAccountOfPeriod" resultType="map">
|
||||
<include refid="targetGroupCte" />
|
||||
SELECT A.gid, A.reg_time, A.user_id, A.name, A.nick_name, BG.name AS biz_group_name
|
||||
FROM account AS A
|
||||
LEFT JOIN biz_group BG ON BG.biz_group_id = A.biz_group_id
|
||||
WHERE A.state != 2
|
||||
AND #{date_start} <= DATE(A.reg_time) AND DATE(A.reg_time) <= #{date_end}
|
||||
<if test='is_all == false'>
|
||||
AND A.biz_group_id IN ( SELECT biz_group_id FROM target_group )
|
||||
</if>
|
||||
ORDER BY A.reg_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectGoodsOfPeriod" resultType="map">
|
||||
<include refid="targetGroupCte" />
|
||||
SELECT G.goods_id, G.reg_time, G.code, G.name, G.price, BG.name AS biz_group_name
|
||||
FROM goods AS G
|
||||
LEFT JOIN biz_group BG ON BG.biz_group_id = G.biz_group_id
|
||||
WHERE G.state != 2
|
||||
AND #{date_start} <= DATE(G.reg_time) AND DATE(G.reg_time) <= #{date_end}
|
||||
<if test='is_all == false'>
|
||||
AND G.biz_group_id IN ( SELECT biz_group_id FROM target_group )
|
||||
</if>
|
||||
ORDER BY G.reg_time DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.handong.smartservice.mapper.DeviceErrorMapper">
|
||||
|
||||
<select id="selectDeviceError" resultType="map">
|
||||
<if test='is_group_access == false'>
|
||||
WITH target_group AS (
|
||||
WITH RECURSIVE group_tree AS (
|
||||
SELECT
|
||||
BG1.biz_group_id,
|
||||
1 AS depth
|
||||
FROM biz_group BG1
|
||||
WHERE BG1.state != 2 AND BG1.biz_group_id = #{biz_group_id}
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
BG2.biz_group_id,
|
||||
GT.depth + 1
|
||||
FROM biz_group BG2
|
||||
INNER JOIN group_tree GT ON BG2.pid = GT.biz_group_id
|
||||
WHERE BG2.state != 2 AND GT.depth < 10
|
||||
)
|
||||
SELECT biz_group_id
|
||||
FROM group_tree
|
||||
)
|
||||
</if>
|
||||
SELECT
|
||||
<choose>
|
||||
<when test='isCount == true'>
|
||||
COUNT(*)
|
||||
</when>
|
||||
<otherwise>
|
||||
E.device_error_id, E.reg_time, E.device_id, D.name AS device_name, E.type, E.uid1, E.uid1_type,
|
||||
E.error_code, E.error_type
|
||||
</otherwise>
|
||||
</choose>
|
||||
FROM device_error AS E
|
||||
LEFT JOIN device D ON E.device_id = D.device_id
|
||||
WHERE
|
||||
<choose>
|
||||
<when test='is_group_access == false'>
|
||||
E.biz_group_id IN ( SELECT biz_group_id FROM target_group )
|
||||
</when>
|
||||
<otherwise>
|
||||
E.biz_group_id = #{biz_group_id}
|
||||
</otherwise>
|
||||
</choose>
|
||||
<if test='date_start != null and date_start != ""'>AND #{date_start} <= DATE(E.reg_time)</if>
|
||||
<if test='date_end != null and date_end != ""'>AND DATE(E.reg_time) <= #{date_end}</if>
|
||||
<if test='device_name != null and device_name != ""'>AND D.name like CONCAT('%', #{device_name}, '%')</if>
|
||||
<if test='uid1 != null and uid1 != ""'>AND E.uid1 = #{uid1}</if>
|
||||
<if test='uid1_type != null and uid1_type != 0'>AND E.uid1_type = #{uid1_type}</if>
|
||||
<if test='type != null and type != ""'>AND E.type = #{type}</if>
|
||||
<if test='error_code != null and error_code != ""'>AND E.error_code like CONCAT('%', #{error_code}, '%')</if>
|
||||
<if test='error_type != null and error_type != 0'>AND E.error_type = #{error_type}</if>
|
||||
<if test='isCount == false and is_excel == false'>
|
||||
ORDER BY E.device_error_id DESC LIMIT #{limit} OFFSET #{offset}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectDeviceErrorById" resultType="map">
|
||||
SELECT
|
||||
E.device_error_id, E.reg_time, E.biz_group_id, E.device_id, D.name AS device_name,
|
||||
E.type, E.uid1, E.uid1_type, E.error_code, E.error_type
|
||||
FROM device_error AS E
|
||||
LEFT JOIN device D ON E.device_id = D.device_id
|
||||
WHERE E.device_error_id = #{device_error_id}
|
||||
</select>
|
||||
|
||||
<insert id="insertDeviceError" parameterType="map">
|
||||
INSERT INTO device_error (type, biz_group_id, device_id, uid1, uid1_type, error_code, error_type)
|
||||
VALUES (#{type}, #{biz_group_id}, #{device_id}, #{uid1}, #{uid1_type}, #{error_code}, #{error_type})
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
@@ -63,11 +63,17 @@
|
||||
COUNT(*)
|
||||
</when>
|
||||
<otherwise>
|
||||
T.reg_time, T.order_time, D.name AS device_name, T.amount, T.type, T.approval, T.uid1, T.pay_name, T.pay_vendor, T.column_no, T.code, T.goods_name, T.pay_unique_num, T.order_time
|
||||
T.reg_time, T.order_time, D.name AS device_name, T.amount, T.type, T.approval, T.uid1, T.pay_name, T.pay_vendor, T.column_no, T.code, T.goods_name, T.pay_unique_num, T.order_time,
|
||||
T.card_num, T.rtid,
|
||||
/* the original approval, shown under a credit cancel row */
|
||||
ORG.reg_time AS org_reg_time, ORG.order_time AS org_order_time, ORG.type AS org_type, ORG.amount AS org_amount,
|
||||
ORG.approval AS org_approval, ORG.card_num AS org_card_num, ORG.pay_name AS org_pay_name, ORG.pay_vendor AS org_pay_vendor,
|
||||
ORG.column_no AS org_column_no, ORG.code AS org_code, ORG.goods_name AS org_goods_name
|
||||
</otherwise>
|
||||
</choose>
|
||||
FROM transactions AS T
|
||||
JOIN device D ON T.device_id = D.device_id
|
||||
LEFT JOIN transactions ORG ON ORG.transaction_id = T.rtid
|
||||
WHERE
|
||||
<choose>
|
||||
<when test='is_group_access == false'>
|
||||
|
||||
Reference in New Issue
Block a user