consumer模块完成度95%,实现数据库多端注册登录,优化安卓端小程序bug
This commit is contained in:
@@ -703,14 +703,17 @@ export class AkSupa {
|
||||
if (this.apikey == null || this.apikey.trim() === '' || this.apikey === 'your-anon-key') {
|
||||
throw new Error('Supabase 配置错误:请在 ak/config.uts 中设置 SUPA_KEY(当前为占位符)');
|
||||
}
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
const reqData = new UTSJSONObject()
|
||||
reqData.set('email', email)
|
||||
reqData.set('password', password)
|
||||
const res = await AkReq.request({
|
||||
url: this.baseUrl + '/auth/v1/token?grant_type=password',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json'
|
||||
} as UTSJSONObject,
|
||||
data: { email, password } as UTSJSONObject,
|
||||
headers: headers,
|
||||
data: reqData,
|
||||
contentType: 'application/json'
|
||||
}, false);
|
||||
// 如果响应不是 2xx(例如 401),提取后端错误信息并抛出,便于上层显示具体原因
|
||||
@@ -720,7 +723,14 @@ export class AkSupa {
|
||||
try {
|
||||
if (res.data != null) {
|
||||
const obj = new UTSJSONObject(res.data);
|
||||
msg = obj.getString('message') ?? obj.getString('error') ?? obj.getString('msg') ?? obj.getString('description') ?? obj.getString('error_description') ?? msg;
|
||||
const rawMsg = obj.getString('message') ?? obj.getString('error') ?? obj.getString('msg') ?? obj.getString('description') ?? obj.getString('error_description') ?? '';
|
||||
|
||||
// 核心修复:在这里拦截英文错误并转换为中文
|
||||
if (rawMsg.includes('Invalid login credentials')) {
|
||||
msg = '用户名或密码错误';
|
||||
} else if (rawMsg != '') {
|
||||
msg = rawMsg;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
@@ -763,15 +773,26 @@ export class AkSupa {
|
||||
};
|
||||
}
|
||||
|
||||
async signUp(email : string, password : string) : Promise<UTSJSONObject> {
|
||||
async signUp(email : string, password : string, options : UTSJSONObject | null = null) : Promise<UTSJSONObject> {
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
const data = new UTSJSONObject()
|
||||
data.set('email', email)
|
||||
data.set('password', password)
|
||||
|
||||
if (options != null) {
|
||||
const dataField = options.getJSON('data')
|
||||
if (dataField != null) {
|
||||
data.set('data', dataField)
|
||||
}
|
||||
}
|
||||
|
||||
const res = await AkReq.request({
|
||||
url: this.baseUrl + '/auth/v1/signup',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json'
|
||||
} as UTSJSONObject,
|
||||
data: { email, password } as UTSJSONObject,
|
||||
headers: headers,
|
||||
data: data,
|
||||
contentType: 'application/json'
|
||||
}, false);
|
||||
return res.data as UTSJSONObject;
|
||||
@@ -786,11 +807,10 @@ export class AkSupa {
|
||||
*/
|
||||
async select(table : string, filter ?: string | null, options ?: AkSupaSelectOptions) : Promise<AkReqResponse<any>> {
|
||||
let url = this.baseUrl + '/rest/v1/' + table;
|
||||
let headers = {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${AkReq.getToken() ?? ''}`
|
||||
} as UTSJSONObject;
|
||||
let headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
headers.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)
|
||||
let params : string[] = [];
|
||||
if (options != null) {
|
||||
if (options.columns != null && !(options.columns == "")) params.push('select=' + encodeURIComponent(options.columns ?? ""));
|
||||
@@ -876,20 +896,17 @@ async select_uts(table : string, filter ?: UTSJSONObject | null, options ?: AkSu
|
||||
*/
|
||||
async insert(table : string, row : UTSJSONObject | Array<UTSJSONObject>) : Promise<AkReqResponse<any>> {
|
||||
const url = this.baseUrl + '/rest/v1/' + table;
|
||||
const headers = {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${AkReq.getToken() ?? ''}`,
|
||||
Prefer: 'return=representation'
|
||||
} as UTSJSONObject;
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
headers.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)
|
||||
headers.set('Prefer', 'return=representation')
|
||||
|
||||
// 如果是数组,直接传递;如果是单个对象,也直接传递
|
||||
// Supabase REST API 原生支持两种格式
|
||||
let reqOptions : AkReqOptions = {
|
||||
url,
|
||||
method: 'POST',
|
||||
headers,
|
||||
data: row, // 可以是单个对象或数组
|
||||
data: row,
|
||||
contentType: 'application/json'
|
||||
};
|
||||
return await this.requestWithAutoRefresh(reqOptions);
|
||||
@@ -907,12 +924,11 @@ async update(table : string, filter : string | null, values : UTSJSONObject) : P
|
||||
if (filter!=null && filter !== "") {
|
||||
url += '?' + filter;
|
||||
}
|
||||
const headers = {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${AkReq.getToken() ?? ''}`,
|
||||
Prefer: 'return=representation'
|
||||
} as UTSJSONObject;
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
headers.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)
|
||||
headers.set('Prefer', 'return=representation')
|
||||
let reqOptions : AkReqOptions = {
|
||||
url,
|
||||
method: 'PATCH',
|
||||
@@ -934,12 +950,11 @@ async delete(table : string, filter : string | null) : Promise<AkReqResponse<any
|
||||
if (filter!=null && filter !== "") {
|
||||
url += '?' + filter;
|
||||
}
|
||||
const headers = {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${AkReq.getToken() ?? ''}`,
|
||||
Prefer: 'return=representation'
|
||||
} as UTSJSONObject;
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
headers.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)
|
||||
headers.set('Prefer', 'return=representation')
|
||||
let reqOptions : AkReqOptions = {
|
||||
url,
|
||||
method: 'DELETE',
|
||||
@@ -956,17 +971,16 @@ async delete(table : string, filter : string | null) : Promise<AkReqResponse<any
|
||||
* @returns AkReqResponse<any>
|
||||
*/
|
||||
async rpc(functionName : string, params ?: UTSJSONObject) : Promise<AkReqResponse<any>> {
|
||||
const url = `${this.baseUrl}/rest/v1/rpc/${functionName}`;
|
||||
const headers = {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${AkReq.getToken() ?? ''}`
|
||||
} as UTSJSONObject;
|
||||
const url = this.baseUrl + '/rest/v1/rpc/' + functionName;
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
headers.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)
|
||||
let reqOptions : AkReqOptions = {
|
||||
url,
|
||||
method: 'POST',
|
||||
headers,
|
||||
data: params ?? {},
|
||||
data: params ?? new UTSJSONObject(),
|
||||
contentType: 'application/json'
|
||||
};
|
||||
return await this.requestWithAutoRefresh(reqOptions);
|
||||
@@ -998,14 +1012,16 @@ async delete(table : string, filter : string | null) : Promise<AkReqResponse<any
|
||||
async refreshSession() : Promise<boolean> {
|
||||
if (this.session == null || this.session?.refresh_token == null) return false;
|
||||
try {
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
const data = new UTSJSONObject()
|
||||
data.set('refresh_token', this.session?.refresh_token)
|
||||
const res = await AkReq.request({
|
||||
url: this.baseUrl + '/auth/v1/token?grant_type=refresh_token',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
apikey: this.apikey,
|
||||
'Content-Type': 'application/json'
|
||||
} as UTSJSONObject,
|
||||
data: { refresh_token: this.session?.refresh_token } as UTSJSONObject,
|
||||
headers: headers,
|
||||
data: data,
|
||||
contentType: 'application/json'
|
||||
}, false);
|
||||
if (res.status == 200 && (res.data != null)) {
|
||||
@@ -1034,6 +1050,23 @@ async delete(table : string, filter : string | null) : Promise<AkReqResponse<any
|
||||
}
|
||||
}
|
||||
|
||||
async updateUserMetadata(metadata: UTSJSONObject): Promise<UTSJSONObject> {
|
||||
const headers = new UTSJSONObject()
|
||||
headers.set('apikey', this.apikey)
|
||||
headers.set('Content-Type', 'application/json')
|
||||
headers.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)
|
||||
const data = new UTSJSONObject()
|
||||
data.set('data', metadata)
|
||||
const res = await AkReq.request({
|
||||
url: this.baseUrl + '/auth/v1/user',
|
||||
method: 'PUT',
|
||||
headers: headers,
|
||||
data: data,
|
||||
contentType: 'application/json'
|
||||
}, false);
|
||||
return res.data as UTSJSONObject;
|
||||
}
|
||||
|
||||
// AkSupa类内新增:自动刷新封装
|
||||
async requestWithAutoRefresh(reqOptions : AkReqOptions, isRetry = false) : Promise<AkReqResponse<any>> {
|
||||
let res = await AkReq.request(reqOptions, false);
|
||||
|
||||
Reference in New Issue
Block a user