From 2794fe393d231c86e6adb4f1441dabfe45853223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E7=A4=BC=E6=88=90?= Date: Wed, 19 Apr 2023 17:49:25 +0800 Subject: [PATCH] simple terminal --- .../http_handler/http_terminal_handler.erl | 155 +++++++++--------- apps/iot/src/model/terminal_model.erl | 6 + 2 files changed, 85 insertions(+), 76 deletions(-) diff --git a/apps/iot/src/http_handler/http_terminal_handler.erl b/apps/iot/src/http_handler/http_terminal_handler.erl index 597391e..f5b4f19 100644 --- a/apps/iot/src/http_handler/http_terminal_handler.erl +++ b/apps/iot/src/http_handler/http_terminal_handler.erl @@ -17,12 +17,10 @@ handle_request("POST", "/terminal/create", _, TerminalInfo) -> lager:debug("[terminal_handler] create post params: ~p", [TerminalInfo]), - case valid_terminal_info(TerminalInfo) of - true -> - TerminalId = id_generator_model:new_terminal_id(), - Terminal = convert_terminal_info(TerminalId, TerminalInfo), - - case terminal_model:add_terminal(Terminal) of + case convert_terminal_info(TerminalInfo) of + {ok, Terminal} -> + TerminalId = terminal_model:next_id(), + case terminal_model:add_terminal(Terminal#terminal{terminal_id = TerminalId}) of ok -> {ok, 200, iot_util:json_data(TerminalId)}; {error, Reason} when is_binary(Reason) -> @@ -31,8 +29,7 @@ handle_request("POST", "/terminal/create", _, TerminalInfo) -> {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(-1, <<"database error">>)} end; - false -> - Error = terminal_error(TerminalInfo), + {error, Error} -> {ok, 200, iot_util:json_error(-1, Error)} end; @@ -40,35 +37,29 @@ handle_request("POST", "/terminal/create", _, TerminalInfo) -> handle_request("POST", "/terminal/batch_import", _, TerminalInfos) -> lager:debug("[terminal_handler] batch_import post params: ~p", [TerminalInfos]), - %% serial_number是必填项 - case lists:any(fun(Info) -> not is_map_key(<<"serial_number">>, Info) orelse maps:get(<<"serial_number">>, Info) == <<"">> end, TerminalInfos) of - true -> - {ok, 200, iot_util:json_error(-1, <<"serial_number missed">>)}; - false -> - case lists:all(fun valid_terminal_info/1, TerminalInfos) of - true -> - ImportResult = lists:map(fun(TerminalInfo = #{<<"serial_number">> := SerialNumber}) -> - TerminalId = id_generator_model:new_terminal_id(), - Terminal = convert_terminal_info(TerminalId, TerminalInfo), - case terminal_model:add_terminal(Terminal) of - ok -> - {SerialNumber, TerminalId}; - {error, Reason} when is_binary(Reason) -> - lager:debug("[host_handler] add_host get error: ~p", [Reason]), - {SerialNumber, Reason}; - {error, Reason} -> - {SerialNumber, <<"failed">>} - end - end, TerminalInfos), + {SuccessList, FailedList} = lists:foldl(fun(TerminalInfo, {SuccessList0, FailedList0}) -> + case convert_terminal_info(TerminalInfo) of + {ok, Terminal = #terminal{serial_number = SerialNumber}} -> + TerminalId = terminal_model:next_id(), + case terminal_model:add_terminal(Terminal#terminal{terminal_id = TerminalId}) of + ok -> + SuccessItem = #{<<"serial_number">> => SerialNumber, <<"terminal_id">> => TerminalId}, + {[SuccessItem|SuccessList0], FailedList0}; + {error, Reason} when is_binary(Reason) -> + ErrorItem = maps:put(<<"error_message">>, Reason, TerminalInfo), + {SuccessList0, [ErrorItem|FailedList0]} + end; + {error, Reason} -> + ErrorItem = maps:put(<<"error_message">>, Reason, TerminalInfo), + {SuccessList0, [ErrorItem|FailedList0]} + end + end, {[], []}, TerminalInfos), + ImportResult = #{ + <<"success_list">> => lists:reverse(SuccessList), + <<"failed_list">> => lists:reverse(FailedList) + }, - {ok, 200, iot_util:json_data(ImportResult)}; - false -> - %% 反馈错误信息 - InvalidTerminalInfos = lists:filter(fun(Info) -> not valid_terminal_info(Info) end, TerminalInfos), - ErrorInfos = lists:map(fun(Info = #{<<"serial_number">> := SerialNumber}) -> {SerialNumber, terminal_error(Info)} end, InvalidTerminalInfos), - {ok, 200, iot_util:json_error(-1, maps:from_list(ErrorInfos))} - end - end; + {ok, 200, iot_util:json_data(ImportResult)}; %% 获取终端的统计信息 handle_request("GET", "/terminal/stat", _, _) -> @@ -161,46 +152,58 @@ handle_request(_, Path, _, _) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 将map转换成record -convert_terminal_info(TerminalId, TerminalInfo) when is_integer(TerminalId), is_map(TerminalInfo) -> - #terminal{ - terminal_id = TerminalId, - %% 关联主机 - host_id = maps:get(<<"host_id">>, TerminalInfo, <<"">>), - %% 序列号 - serial_number = maps:get(<<"serial_number">>, TerminalInfo, <<"">>), - %% 名称 - name = maps:get(<<"name">>, TerminalInfo, <<"">>), - %% 设备编码 - code = maps:get(<<"code">>, TerminalInfo, <<"">>), - %% 接入协议 - access_protocol = maps:get(<<"access_protocol">>, TerminalInfo, <<"">>), - %% 产品ID,枚举类型 - product_id = maps:get(<<"product_id">>, TerminalInfo, 0), - %% 厂商ID,枚举类型 - vendor_id = maps:get(<<"vendor_id">>, TerminalInfo, 0), - %% 型号 - model = maps:get(<<"model">>, TerminalInfo, <<"">>), - %% 所在单元ID,管理系统负责 - cell_id = maps:get(<<"cell_id">>, TerminalInfo, 0), - %% 终端状态 - status = ?TERMINAL_STATUS_OFFLINE, - %% 最后上线时间 - update_ts = 0 - }. +convert_terminal_info(#{<<"host_id">> := HostId, <<"serial_number">> := SerialNumber, <<"name">> := Name, <<"code">> := Code, <<"access_protocol">> := AccessProtocol, + <<"product_id">> := ProductId, <<"vendor_id">> := VendorId, <<"model">> := Model, <<"cell_id">> := CellId}) -> -%% 检查是否是合法的主机信息 -valid_terminal_info(#{<<"name">> := Name, <<"model">> := Model, <<"cell_id">> := CellId, <<"serial_number">> := SerialNumber}) -> - Name =/= <<"">> andalso Model =/= <<"">> andalso CellId > 0 andalso SerialNumber =/= <<"">>. + CheckResult = if + Name == <<>> -> + {error, <<"name is empty">>}; + HostId == <<>> -> + {error, <<"host_id is empty">>}; + SerialNumber == <<>> -> + {error, <<"serial_number is empty">>}; + Code == <<>> -> + {error, <<"code is empty">>}; + AccessProtocol == <<>> -> + {error, <<"access_protocol is empty">>}; + Model == <<>> -> + {error, <<"model is empty">>}; + not is_integer(ProductId) orelse ProductId < 0 -> + {error, <<"product_id is error">>}; + not is_integer(VendorId) orelse VendorId < 0 -> + {error, <<"vendor_id is error">>}; + not is_integer(CellId) orelse CellId < 0 -> + {error, <<"cell_id is error">>}; + true -> + ok + end, -%% 获取错误信息 -terminal_error(M) when is_map(M) -> - if - not is_map_key(<<"name">>, M) orelse map_get(<<"name">>, M) == <<>> -> - <<"name is empty">>; - not is_map_key(<<"model">>, M) orelse map_get(<<"model">>, M) == <<>> -> - <<"model is empty">>; - not is_map_key(<<"serial_number">>, M) orelse map_get(<<"serial_number">>, M) == <<>> -> - <<"serial_number is empty">>; - true -> - <<"unknown error">> + case CheckResult of + ok -> + {ok, #terminal{ + %% 关联主机 + host_id = HostId, + %% 序列号 + serial_number = SerialNumber, + %% 名称 + name = Name, + %% 设备编码 + code = Code, + %% 接入协议 + access_protocol = AccessProtocol, + %% 产品ID,枚举类型 + product_id = ProductId, + %% 厂商ID,枚举类型 + vendor_id = VendorId, + %% 型号 + model = Model, + %% 所在单元ID + cell_id = CellId, + %% 终端状态 + status = ?TERMINAL_STATUS_OFFLINE, + %% 最后上线时间 + update_ts = iot_util:timestamp() + }}; + {error, Reason} -> + {error, Reason} end. \ No newline at end of file diff --git a/apps/iot/src/model/terminal_model.erl b/apps/iot/src/model/terminal_model.erl index 22638c1..9352c5d 100644 --- a/apps/iot/src/model/terminal_model.erl +++ b/apps/iot/src/model/terminal_model.erl @@ -14,9 +14,15 @@ -define(TAB_NAME, terminal). %% API +-export([next_id/0]). -export([get_terminal/1, get_all_terminals/0, get_host_terminals/1, find_terminals/3, get_stat/0, table_size/0, match_spec/1]). -export([change_status/2, delete/1, to_map/1, add_terminal/1, update_terminal/2]). +%% 生成信息的id信息 +-spec next_id() -> Id :: integer(). +next_id() -> + id_generator_model:new_terminal_id(). + -spec get_terminal(TerminalId :: integer()) -> {ok, #terminal{}} | undefined. get_terminal(TerminalId) when is_integer(TerminalId) -> case mnesia:dirty_read(?TAB_NAME, TerminalId) of