add rest api

This commit is contained in:
DevWiki 2024-09-11 19:27:24 +08:00
parent ed6cbec7c9
commit 3a4338c99a
10 changed files with 217 additions and 56 deletions

View File

@ -32,10 +32,10 @@ export class MyApp {
atManager.requestPermissionsFromUser(MyApp.uiAbilityContext,
['ohos.permission.INTERNET'])
.then((data) => {
Log.i(TAG, 'requestBasicPermission, data:' + data.permissions[0])
Log.info(TAG, 'requestBasicPermission, data:' + data.permissions[0])
})
.catch((err: BusinessError) => {
Log.i(TAG, 'requestBasicPermission, error:' + err.message)
Log.info(TAG, 'requestBasicPermission, error:' + err.message)
})
} catch (err) {
}

View File

@ -113,17 +113,17 @@ struct Index {
}).then((result: promptAction.ShowDialogSuccessResponse) => {
if (result.index === 0) {
// 用户点击了“取消”按钮
Log.i('User canceled the operation.');
Log.info('User canceled the operation.');
} else if (result.index === 1) {
// 用户点击了“确认”按钮
Log.i('User confirmed the operation.');
Log.info('User confirmed the operation.');
// 调用router.back()方法,返回上一个页面
router.back();
}
}).catch((err: Error) => {
let message = (err as BusinessError).message
let code = (err as BusinessError).code
Log.i(`Invoke showDialog failed, code is ${code}, message is ${message}`);
Log.info(`Invoke showDialog failed, code is ${code}, message is ${message}`);
})
return true;
}

View File

@ -0,0 +1,45 @@
import { BusinessError } from '@ohos.base';
export class APIQuery extends Map<string, string|number|boolean> { }
export interface APIHeader {
[key: string]: string;
}
export enum APIRequestMethod {
GET, POST, PUT, DELETE
}
export class APIRequest {
url: string = "";
method: APIRequestMethod = APIRequestMethod.POST;
extraData?: string | Object | ArrayBuffer;
header?: APIHeader[];
}
export class APIResult<T> {
httpCode: number;
businessError?: BusinessError;
error?: APIError;
data?: T;
}
export interface APIError{
errors: string[];
message: string;
url: string;
}
export interface Organization {
id: number;
name: string;
full_name: string;
email: string;
avatar_url: string;
description: string;
website: string;
location: string;
visibility: string;
repo_admin_change_team_access: boolean;
username: string;
}

View File

@ -0,0 +1,121 @@
import http from '@ohos.net.http';
import { Log } from '@devwiki/base/Index';
import { APIError, APIHeader, APIQuery, APIRequestMethod, Organization } from './APIModel';
import { APIRequest } from './APIModel';
import { APIResult } from './APIModel';
const TAG = '[RestAPI]'
export class RestAPI {
private baseUrl: string ='https://gitea.com/api/v1';
private readonly timeout = 10000;
private baseQuery: string = '?=0';
private defaultHeaders: APIHeader[] = [
{ "connection" : "keep-alive" },
{ 'accept-encoding' : 'gzip, deflate, br, zstd' },
{ 'accept-language' : 'zh-CN,zh;q=0.9,en;q=0.8' }
];
public getAllOrganizations(callback: (result: APIResult<Organization[]>) => void) {
let path = '/orgs'
let url = this.getUrl(path);
Log.info(TAG, 'getOrgByName url:' + url);
this.request({
url: url,
method: APIRequestMethod.GET
}, callback);
}
public getAllOrganizationsByPage(page: number, limit: number, callback: (result: APIResult<Organization[]>) => void) {
let path = '/orgs'
let extraQuery = new APIQuery()
extraQuery.set('page', page);
extraQuery.set('limit', limit);
let url = this.getUrl(path, extraQuery);
Log.info(TAG, 'getOrgByName url:' + url);
this.request({
url: url,
method: APIRequestMethod.GET
}, callback);
}
public getOrgByName(name: string, callback: (result: APIResult<Organization>) => void) {
let path = `/orgs/${name}`;
let url = this.getUrl(path);
Log.info(TAG, 'getOrgByName url:' + url);
this.request({
url: url,
method: APIRequestMethod.GET
}, callback);
}
request<T>(apiReq: APIRequest, callback: (result: APIResult<T>) => void) {
Log.info(TAG, 'request, url:' + apiReq.url)
let httpRequest = http.createHttp();
let option:http.HttpRequestOptions = this.createHttpRequestOption(apiReq);
httpRequest.request(apiReq.url, option, (error, resp) =>{
let result: APIResult<T> = new APIResult();
if (!error) {
Log.info(TAG, 'result, httpCode:' + result.httpCode + ', data:' + resp.result?.toString())
result.httpCode = resp.responseCode;
try {
if (resp.responseCode == http.ResponseCode.OK) {
result.data = JSON.parse(resp.result?.toString()) as T
} else {
result.error = JSON.parse(resp.result?.toString()) as APIError;
}
} catch (e) {
Log.error(TAG, 'result json parse error:' + e)
}
callback?.(result);
} else {
result.businessError = error;
callback?.(result);
Log.error(TAG, `request ${apiReq.url} failed, code:${error.code}, message:${error.message}`)
}
httpRequest.destroy();
});
}
private createHttpRequestOption(apiReq: APIRequest): http.HttpRequestOptions{
let headers: APIHeader[] = this.defaultHeaders;
if (apiReq.header) {
apiReq.header.forEach((header) =>{
headers.push(header);
})
}
let method: http.RequestMethod = http.RequestMethod.GET;
if (apiReq.method == APIRequestMethod.POST) {
method = http.RequestMethod.POST;
} else if (apiReq.method == APIRequestMethod.PUT) {
method = http.RequestMethod.PUT;
} else if (apiReq.method == APIRequestMethod.DELETE) {
method = http.RequestMethod.DELETE;
} else {
method = http.RequestMethod.GET;
}
return {
method: method,
extraData : apiReq.extraData,
readTimeout : this.timeout,
connectTimeout: this.timeout,
expectDataType: http.HttpDataType.STRING,
header: headers,
usingProtocol: http.HttpProtocol.HTTP1_1
};
}
private getUrl(path: string, extraQuery?: APIQuery): string {
let url = `${this.baseUrl}${path}${this.baseQuery}`;
if (extraQuery) {
for (let key of extraQuery.keys()) {
url += `&${key}=${extraQuery.get(key)}`
}
}
Log.debug(TAG, `get url, path: ${path}, url:${url}`)
return url;
}
}

View File

@ -1,6 +1,8 @@
import { Log } from '@devwiki/base/Index';
import axios, { AxiosError, AxiosResponse } from '@ohos/axios'
import http from '@ohos.net.http';
import { RestAPI } from './RestAPI';
import { Organization } from './APIModel';
const TAG = '[RestAPIPage]'
@ -17,15 +19,28 @@ struct RestAPIPage {
direction: FlexDirection.Column,
alignItems: ItemAlign.Center
}) {
Button("GetByAxios").onClick(() =>{
this.viewModel.getServerVersionByAxios();
}).margin({top: 20})
Refresh({
refreshing: $$this.viewModel.refreshing,
}){
List(){
ForEach(this.viewModel.orsg, (org: Organization, index: number) =>{
ListItem(){
Row() {
Image(org.avatar_url).width(36).height(36).objectFit(ImageFit.Contain)
Text(org.name)
}.justifyContent(FlexAlign.Start).alignItems(VerticalAlign.Center).height(48)
}
})
}.width('100%').height('100%').layoutWeight(1)
}.pullToRefresh(true)
.onRefreshing(() =>{
this.viewModel.getAllOrgs();
})
Button("GetByHttp").onClick(() =>{
this.viewModel.getServerVersionByHttp();
this.viewModel.getAllOrgs();
}).margin({top: 20})
Text(this.viewModel.serverVersion).margin({top: 20})
}.width('80%')
}.width('100%')
}
@ -34,40 +49,20 @@ struct RestAPIPage {
class RestAPIViewModel {
readonly viewUrl: string = 'https://music.devwiki.net/rest/ping.view?v=1.16.1&c=myapp&f=json';
serverVersion: string = '123'
orsg: Organization[] = []
refreshing: boolean = false;
async getServerVersionByAxios() {
this.serverVersion = ''
await axios({
method: "post",
url: this.viewUrl
}).then((response: AxiosResponse) => {
if (response.status == 200) {
let version:string = response.data['subsonic-response']['serverVersion'];
this.serverVersion = version;
Log.i(`serverVersion: ${this.serverVersion}`)
private restAPI: RestAPI = new RestAPI();
getAllOrgs() {
this.restAPI.getAllOrganizations((result) => {
if (result.data) {
this.orsg = result.data;
}
}).catch((error: AxiosError) => {
Log.e(error.message);
this.refreshing = false;
})
}
getServerVersionByHttp() {
this.serverVersion = ''
let httpRequest = http.createHttp();
let option:http.HttpRequestOptions = {
method: http.RequestMethod.GET
};
httpRequest.request(this.viewUrl, option, (error, resp) =>{
if (!error) {
Log.i(TAG, 'request http code:' + resp.responseCode)
let version:string = resp.result['subsonic-response']['serverVersion'];
this.serverVersion = version;
} else {
Log.e(TAG, `request failed, code:${error.code}, message:${error.message}`)
}
httpRequest.destroy();
});
}
}

View File

@ -26,10 +26,10 @@ class TcpSocket {
let message = String.fromCharCode(messages);
messageView += message;
}
Log.i(`receive message: ${messageView}`)
Log.info(`receive message: ${messageView}`)
})
this.tcp.on('error', (error) => {
Log.i(`tcp error: ${error.message}`)
Log.info(`tcp error: ${error.message}`)
})
}
@ -40,19 +40,19 @@ class TcpSocket {
this.tcp.bind(address)
this.tcp.connect(this.connectOptions, (error) => {
if (error) {
Log.e(`connect fail: ${error.message}`);
Log.error(`connect fail: ${error.message}`);
return;
}
Log.i('connect success')
Log.info('connect success')
})
}
send(text: string) {
let option: socket.TCPSendOptions = { data: text}
this.tcp.send(option).then(() => {
Log.i(`send data: ${text} success`)
Log.info(`send data: ${text} success`)
}).catch((error: BusinessError) => {
Log.e(`send data: ${text} error: ${error.message}`)
Log.error(`send data: ${text} error: ${error.message}`)
})
}
}

View File

@ -13,7 +13,7 @@ struct SetLanguagePage {
aboutToAppear(): void {
let languages:string[] = i18n.System.getSystemLanguages();
languages.forEach((value, index) => {
Log.i(TAG, `${index.toString()}:${value}`)
Log.info(TAG, `${index.toString()}:${value}`)
})
}

View File

@ -34,12 +34,12 @@ export class BaseLocalStorage {
let options: dataPreferences.Options = { name: BaseLocalStorage.XY_DP_Name };
this.preferences = dataPreferences.getPreferencesSync(this.context, options);
} else {
Log.i("LocalStorage is already init.")
Log.info("LocalStorage is already init.")
}
}
public putData(key: string, value: dataPreferences.ValueType) {
Log.i(`put sp data, key:${key}, value:${value}`)
Log.info(`put sp data, key:${key}, value:${value}`)
this.preferences?.putSync(key, value);
this.preferences?.flush();
}
@ -51,7 +51,7 @@ export class BaseLocalStorage {
public getData(key: string, defaultValue: dataPreferences.ValueType): dataPreferences.ValueType | undefined {
let value = this.preferences?.getSync(key, defaultValue);
Log.i(`get sp data, key:${key}, value:${value}`)
Log.info(`get sp data, key:${key}, value:${value}`)
return value;
}

View File

@ -7,23 +7,23 @@ let format: string = `%{public}s, %{public}s`;
export class Log {
static d(...args: string[]) {
static debug(...args: string[]) {
hilog.debug(domain, prefix, format, args);
}
static i(...args: string[]) {
static info(...args: string[]) {
hilog.info(domain, prefix, format, args);
}
static w(...args: string[]) {
static warn(...args: string[]) {
hilog.warn(domain, prefix, format, args);
}
static e(...args: string[]) {
static error(...args: string[]) {
hilog.error(domain, prefix, format, args);
}
static f(...args: string[]) {
static fatal(...args: string[]) {
hilog.fatal(domain,prefix, format, args);
}

View File

@ -106,7 +106,7 @@ export class ScreenUtil {
}
setWindowKeepScreenOn(isKeep: boolean) {
Log.i(`setWindowKeepScreenOn:${isKeep}`)
Log.info(`setWindowKeepScreenOn:${isKeep}`)
window.getLastWindow(getContext(this))
.then((windowClass: window.Window) => {
windowClass.setWindowKeepScreenOn(isKeep);