feat(core): sgw-device-ui

This commit is contained in:
Tran Anh Tuan
2025-09-26 18:22:04 +07:00
parent 466e931537
commit 2707b92f7e
88 changed files with 19104 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
import { API_PATH_LOGIN } from '@/constants';
import { request } from '@umijs/max';
export async function login(body: API.LoginRequestBody) {
console.log('Login request body:', body);
return request<API.LoginResponse>(API_PATH_LOGIN, {
method: 'POST',
data: body,
});
}

View File

@@ -0,0 +1,54 @@
import {
API_GET_ALARMS,
API_GET_GPS,
API_PATH_ENTITIES,
API_PATH_SHIP_INFO,
API_SOS,
} from '@/constants';
import { request } from '@umijs/max';
function transformEntityResponse(
raw: API.EntityResponse,
): API.TransformedEntity {
return {
id: raw.id,
value: raw.v,
valueString: raw.vs,
time: raw.t,
type: raw.type,
};
}
export async function getEntities(): Promise<API.TransformedEntity[]> {
const rawList = await request<API.EntityResponse[]>(API_PATH_ENTITIES);
return rawList.map(transformEntityResponse);
}
export async function getShipInfo(): Promise<API.ShipDetail> {
return await request<API.ShipDetail>(API_PATH_SHIP_INFO);
}
export async function queryAlarms(): Promise<API.AlarmResponse> {
return await request<API.AlarmResponse>(API_GET_ALARMS);
}
export async function getGPS() {
return await request<API.GPSResonse>(API_GET_GPS);
}
export async function getSos() {
return await request<API.SosResponse>(API_SOS);
}
export async function deleteSos() {
return await request<API.SosResponse>(API_SOS, {
method: 'DELETE',
});
}
export async function sendSosMessage(message: string) {
return await request<API.SosRequest>(API_SOS, {
method: 'PUT',
params: {
message,
},
});
}

View File

@@ -0,0 +1,10 @@
import { API_GET_ALL_LAYER, API_GET_LAYER_INFO } from '@/constants';
import { request } from '@umijs/max';
export async function getLayer(name: string) {
return request(`${API_GET_LAYER_INFO}/${name}`);
}
export async function getAllLayer() {
return request(API_GET_ALL_LAYER);
}

View File

@@ -0,0 +1,37 @@
import {
API_GET_FISH,
API_GET_TRIP,
API_HAUL_HANDLE,
API_UPDATE_FISHING_LOGS,
API_UPDATE_TRIP_STATUS,
} from '@/constants';
import { request } from '@umijs/max';
export async function getTrip(): Promise<API.Trip> {
return request<API.Trip>(API_GET_TRIP);
}
export async function updateTripState(body: API.TripUpdateStateRequest) {
return request(API_UPDATE_TRIP_STATUS, {
method: 'PUT',
data: body,
});
}
export async function startNewHaul(body: API.NewFishingLogRequest) {
return request(API_HAUL_HANDLE, {
method: 'PUT',
data: body,
});
}
export async function getFishSpecies() {
return request<API.FishSpeciesResponse[]>(API_GET_FISH);
}
export async function updateFishingLogs(body: API.FishingLog) {
return request(API_UPDATE_FISHING_LOGS, {
method: 'PUT',
data: body,
});
}

View File

@@ -0,0 +1,97 @@
/* eslint-disable */
// 该文件由 OneAPI 自动生成,请勿手动修改!
import { request } from '@umijs/max';
/** 此处后端没有提供注释 GET /api/v1/queryUserList */
export async function queryUserList(
params: {
// query
/** keyword */
keyword?: string;
/** current */
current?: number;
/** pageSize */
pageSize?: number;
},
options?: { [key: string]: any },
) {
return request<API.Result_PageInfo_UserInfo__>('/api/v1/queryUserList', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/v1/user */
export async function addUser(
body?: API.UserInfoVO,
options?: { [key: string]: any },
) {
return request<API.Result_UserInfo_>('/api/v1/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/v1/user/${param0} */
export async function getUserDetail(
params: {
// path
/** userId */
userId?: string;
},
options?: { [key: string]: any },
) {
const { userId: param0 } = params;
return request<API.Result_UserInfo_>(`/api/v1/user/${param0}`, {
method: 'GET',
params: { ...params },
...(options || {}),
});
}
/** 此处后端没有提供注释 PUT /api/v1/user/${param0} */
export async function modifyUser(
params: {
// path
/** userId */
userId?: string;
},
body?: API.UserInfoVO,
options?: { [key: string]: any },
) {
const { userId: param0 } = params;
return request<API.Result_UserInfo_>(`/api/v1/user/${param0}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
params: { ...params },
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 DELETE /api/v1/user/${param0} */
export async function deleteUser(
params: {
// path
/** userId */
userId?: string;
},
options?: { [key: string]: any },
) {
const { userId: param0 } = params;
return request<API.Result_string_>(`/api/v1/user/${param0}`, {
method: 'DELETE',
params: { ...params },
...(options || {}),
});
}

View File

@@ -0,0 +1,16 @@
/* eslint-disable */
// 该文件由 OneAPI 自动生成,请勿手动修改!
import * as AuthController from './AuthController';
import * as DeviceController from './DeviceController';
import * as MapController from './MapController';
import * as TripController from './TripController';
import * as UserController from './UserController';
export default {
UserController,
AuthController,
DeviceController,
MapController,
TripController,
};

331
src/services/controller/typings.d.ts vendored Normal file
View File

@@ -0,0 +1,331 @@
/* eslint-disable */
// 该文件由 OneAPI 自动生成,请勿手动修改!
declare namespace API {
interface LoginRequestBody {
username: string;
password: string;
}
interface LoginResponse {
token?: string;
}
// Thông tin 1 entity
interface Entity {
id: string;
type: string;
name: string;
}
// Trigger điều kiện trong TCR
interface Trigger {
entityID: string;
gt: number;
lt: number;
}
// Command thực thi trong TCR
interface Command {
to: string;
params: string;
type: string;
}
// Cấu hình ngày/tuần/tháng/năm của TCR
interface ActiveDay {
activeDateRange: string[];
dayInWeek: string[];
dayInMonth: string[];
deactiveInYear: string[];
}
// TCR = Trigger Condition Rule
interface TCR {
id: string;
enable: boolean;
description: string;
name: string;
trigger: Trigger[];
conditions: any[]; // chưa rõ cấu trúc nên tạm để any[]
duration: number;
commands: Command[];
sendEvent: boolean;
eventID: string;
makeAlarm: string;
alarmLevel: number;
activeDay: ActiveDay;
activeTime: number[]; // [start, end]
}
// Sự kiện
interface Event {
evtid: string;
content: string;
}
// Node chính (mỗi thiết bị / sensor)
interface Node {
nid: string;
subtype?: string; // có thể không có (ví dụ hum:0:21)
enable: boolean;
name: string;
entities: Entity[];
TCR?: TCR[]; // không phải node nào cũng có
events?: Event[];
}
// Response root
interface NodeResponse {
nodes: Node[];
synced: boolean;
}
interface EntityResponse {
id: string;
v: number;
vs: string;
t: number;
type: string;
}
interface TransformedEntity {
id: string;
value: number;
valueString: string;
time: number;
type: string;
}
interface ShipDetail {
id: string;
thing_id: string;
owner_id: string;
name: string;
ship_type: number;
home_port: number;
ship_length: number;
ship_power: number;
reg_number: string;
imo_number: string;
mmsi_number: string;
fishing_license_number: string;
fishing_license_expiry_date: Date;
province_code: string;
ship_group_id: string;
created_at: Date;
updated_at: Date;
}
interface GPSResonse {
lat: number;
lon: number;
s: number;
h: number;
fishing: boolean;
}
// Trips
interface FishingGear {
name: string;
number: string;
}
interface TripCost {
type: string;
unit: string;
amount: string;
total_cost: string;
cost_per_unit: string;
}
interface TripCrewPerson {
personal_id: string;
name: string;
phone: string;
email: string;
birth_date: Date; // ISO string (có thể chuyển sang Date nếu parse trước)
note: string;
address: string;
created_at: Date;
updated_at: Date;
}
interface TripCrews {
role: string;
joined_at: Date;
left_at: Date | null;
note: string | null;
Person: TripCrewPerson;
}
interface FishingLogInfo {
fish_species_id?: number;
fish_name?: string;
catch_number?: number;
catch_unit?: string;
fish_size?: number;
fish_rarity?: number;
fish_condition?: string;
gear_usage?: string;
}
interface FishingLog {
fishing_log_id: string;
trip_id: string;
start_at: Date; // ISO datetime
end_at: Date; // ISO datetime
start_lat: number;
start_lon: number;
haul_lat: number;
haul_lon: number;
status: number;
weather_description: string;
info?: FishingLogInfo[];
sync: boolean;
}
interface NewFishingLogRequest {
trip_id: string;
start_at: Date; // ISO datetime
start_lat: number;
start_lon: number;
weather_description: string;
}
interface Trip {
id: string;
ship_id: string;
ship_length: number;
vms_id: string;
name: string;
fishing_gears: FishingGear[];
crews?: TripCrews[];
departure_time: string; // ISO datetime string
departure_port_id: number;
arrival_time: string; // ISO datetime string
arrival_port_id: number;
fishing_ground_codes: number[];
total_catch_weight: number | null;
total_species_caught: number | null;
trip_cost: TripCost[];
trip_status: number;
approved_by: string;
notes: string | null;
fishing_logs: FishingLog[] | null; // tuỳ dữ liệu chi tiết có thể định nghĩa thêm
sync: boolean;
}
interface TripUpdateStateRequest {
status: number;
note?: string;
}
interface Alarm {
name: string;
t: number; // timestamp (epoch seconds)
level: number;
id: string;
}
interface AlarmResponse {
alarms: Alarm[];
level: number;
}
//Fish
interface FishSpeciesResponse {
id: number;
name: string;
scientific_name: string;
group_name: string;
species_code: string;
note: string;
default_unit: string;
rarity_level: number;
created_at: string;
updated_at: string;
is_deleted: boolean;
}
interface FishRarity {
id: number;
code: string;
label: string;
description: string;
iucn_code: any;
cites_appendix: any;
vn_law: boolean;
}
// SOS
interface SosRequest {
message?: string;
}
interface SosResponse {
active: boolean;
message?: string;
started_at?: number;
}
// Node
interface Welcome {
nodes?: Node[];
synced?: boolean;
}
interface Node {
nid?: string;
subtype?: string;
enable?: boolean;
name?: string;
entities?: Entity[];
TCR?: Tcr[];
events?: Event[];
}
interface Tcr {
id?: string;
enable?: boolean;
description?: string;
name?: string;
trigger?: Trigger[];
conditions?: any[];
duration?: number;
commands?: Command[];
sendEvent?: boolean;
eventID?: string;
makeAlarm?: string;
alarmLevel?: number;
activeDay?: ActiveDay;
activeTime?: number[];
}
interface ActiveDay {
activeDateRange?: any[];
dayInWeek?: any[];
dayInMonth?: any[];
deactiveInYear?: any[];
}
interface Command {
to?: string;
params?: string;
type?: string;
}
interface Trigger {
entityID?: string;
gt?: number;
lt?: number;
}
interface Entity {
id?: string;
type?: string;
name?: string;
}
interface Event {
evtid?: string;
content?: string;
}
}

View File

@@ -0,0 +1,64 @@
import { createGeoJSONLayer, createLabelAndFillStyle } from '@/utils/mapUtils';
import TileLayer from 'ol/layer/Tile';
import { XYZ } from 'ol/source';
import shipAlarmIcon from '../../assets/ship_alarm.png';
import shipAlarmFishingIcon from '../../assets/ship_alarm_fishing.png';
import shipOnlineIcon from '../../assets/ship_online.png';
import shipOnlineFishingIcon from '../../assets/ship_online_fishing.png';
import shipUndefineIcon from '../../assets/ship_undefine.png';
import shipWarningIcon from '../../assets/ship_warning.png';
import shipWarningFishingIcon from '../../assets/ship_warning_fishing.png';
import shipSosIcon from '../../assets/sos_icon.png';
export const BASEMAP_URL =
'https://cartodb-basemaps-a.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png';
export const BASEMAP_ATTRIBUTIONS = '© OpenStreetMap contributors, © CartoDB';
export const INITIAL_VIEW_CONFIG = {
// Dịch tâm bản đồ ra phía biển và zoom ra xa hơn để thấy bao quát
center: [109.5, 16.0],
zoom: 5.5,
minZoom: 5,
maxZoom: 12,
minScale: 0.1,
maxScale: 0.4,
};
export const osmLayer = new TileLayer({
source: new XYZ({
url: BASEMAP_URL,
attributions: BASEMAP_ATTRIBUTIONS,
}),
});
// const layerVN = await getLayer('base-vn');
export const tinhGeoLayer = createGeoJSONLayer({
data: '',
style: createLabelAndFillStyle('#77BEF0', '#000000'), // vừa màu vừa label
properties: {
name: 'tenTinh',
popupProperties: { 'Dân số': 'danSo', 'Diện tích (km²)': 'dienTich' },
},
});
export const getShipIcon = (type: number, isFishing: boolean) => {
console.log('type, isFishing', type, isFishing);
if (type === 1 && !isFishing) {
return shipWarningIcon;
} else if (type === 2 && !isFishing) {
return shipAlarmIcon;
} else if (type === 0 && !isFishing) {
return shipOnlineIcon;
} else if (type === 1 && isFishing) {
return shipWarningFishingIcon;
} else if (type === 2 && isFishing) {
return shipAlarmFishingIcon;
} else if (type === 0 && isFishing) {
return shipOnlineFishingIcon;
} else if (type === 3) {
return shipSosIcon;
} else {
return shipUndefineIcon;
}
};