feat: 更新环境配置,添加 API 地址,优化数据获取逻辑,支持振动反馈功能

This commit is contained in:
2025-12-18 22:23:18 +07:00
parent 6ceb80e6f2
commit f570cbce84
20 changed files with 259 additions and 92 deletions

View File

@@ -1,5 +1,5 @@
import type { App } from "@riwa/api-types";
import type { Awaitable } from "@vueuse/core";
import type { WatchSource } from "vue";
import { treaty } from "@elysiajs/eden";
import { toastController } from "@ionic/vue";
@@ -12,26 +12,42 @@ const client = treaty<App>(window.location.origin, {
export interface SafeClientOptions {
silent?: boolean;
immediate?: boolean;
watchSource?: WatchSource; // 用于监听的响应式数据源
}
export interface SafeClientReturn<T, E> {
data: Ref<T | null>;
error: Ref<E | null>;
refresh: () => Promise<void>;
isPending: Ref<boolean>;
execute: () => Promise<void>;
onFetchResponse: (callback: (data: T, error: E) => void) => void;
stopWatching?: () => void;
}
export function safeClient<T, E>(
requestPromise: () => Promise<{ data: T; error: E }>,
requestPromise: (() => Promise<{ data: T; error: E }>) | Promise<{ data: T; error: E }>,
options: SafeClientOptions = {},
): SafeClientReturn<T, E> & Promise<SafeClientReturn<T, E>> {
const { immediate = true } = options;
const { immediate = true, watchSource } = options;
const data = ref<T | null>(null);
const error = ref<E | null>(null);
const isPending = ref(false);
let responseCallback: ((data: T, error: E) => void) | null = null;
let stopWatcher: (() => void) | undefined;
const execute = async () => {
const res = await requestPromise();
isPending.value = true;
let request: () => Promise<{ data: T; error: E }>;
if (typeof requestPromise !== "function") {
request = () => Promise.resolve(requestPromise);
}
else {
request = requestPromise;
}
const res = await request().finally(() => {
isPending.value = false;
});
if (res.error) {
let errMsg = "";
@@ -44,6 +60,7 @@ export function safeClient<T, E>(
else if (res.error && "value" in (res.error as unknown as object)) {
errMsg = String((res.error as unknown as { value: string }).value);
}
// if(res.error && typeof res.error === 'object' && 'err' in res.error) {
if (!options.silent) {
const toast = await toastController.create({
message: errMsg,
@@ -69,17 +86,35 @@ export function safeClient<T, E>(
responseCallback = callback;
}
function stopWatching() {
if (stopWatcher) {
stopWatcher();
stopWatcher = undefined;
}
}
// 如果提供了 watchSource则监听其变化
if (watchSource) {
stopWatcher = watch(
watchSource,
() => {
execute();
},
{ immediate: false }, // 不立即执行,避免与 immediate 选项冲突
);
}
const result: SafeClientReturn<T, E> = {
data: data as Ref<T | null>,
error: error as Ref<E | null>,
refresh: execute,
isPending,
execute,
onFetchResponse,
stopWatching,
};
// 创建一个 Promise 并在其上添加属性
const promise = immediate ? execute().then(() => result) : Promise.resolve(result);
// 将 result 的属性添加到 promise 上
Object.assign(promise, result);
return promise as SafeClientReturn<T, E> & Promise<SafeClientReturn<T, E>>;

View File

@@ -45,3 +45,5 @@ export type SupportBanksData = Treaty.Data<typeof client.api.bank_account.banks.
export type AvailableSubscriptionData = Treaty.Data<typeof client.api.rwa.subscription.available_editions.get>;
export type AvailableSubscriptionBody = TreatyQuery<typeof client.api.rwa.subscription.available_editions.get>;
export type RwaData = Treaty.Data<typeof client.api.rwa.subscription.available_editions.get>;