|
|
@@ -1,122 +1,61 @@
|
|
|
import * as Parse from 'parse';
|
|
|
|
|
|
+// 初始化 Parse
|
|
|
+Parse.initialize("dev", "dev");
|
|
|
+Parse.CoreManager.set('SERVER_URL', 'http://dev.fmode.cn:1337/parse');
|
|
|
+
|
|
|
export class CloudObject {
|
|
|
- protected parseObject: Parse.Object;
|
|
|
- className: string;
|
|
|
id: string | null = null;
|
|
|
- createdAt: any;
|
|
|
- updatedAt: any;
|
|
|
data: Record<string, any> = {};
|
|
|
+ createdAt?: Date;
|
|
|
+ updatedAt?: Date;
|
|
|
|
|
|
- constructor(className: string) {
|
|
|
- this.parseObject = new Parse.Object(className);
|
|
|
- this.className = className;
|
|
|
- }
|
|
|
+ constructor(protected className: string) {}
|
|
|
|
|
|
- toPointer() {
|
|
|
- return { "__type": "Pointer", "className": this.className, "objectId": this.id };
|
|
|
+ get(key: string): any {
|
|
|
+ return this.data[key];
|
|
|
}
|
|
|
|
|
|
- set(json: Record<string, any>) {
|
|
|
- Object.keys(json).forEach(key => {
|
|
|
- if (["objectId", "id", "createdAt", "updatedAt", "ACL"].indexOf(key) > -1) {
|
|
|
- if (key === "objectId") this.id = json[key];
|
|
|
- return;
|
|
|
- }
|
|
|
- this.data[key] = json[key];
|
|
|
- });
|
|
|
+ set(key: string | Record<string, any>, value?: any) {
|
|
|
+ if (typeof key === 'string') {
|
|
|
+ this.data[key] = value;
|
|
|
+ } else {
|
|
|
+ Object.assign(this.data, key);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- get(key: string) {
|
|
|
- return this.data[key] || null;
|
|
|
+ toJSON(): Record<string, any> {
|
|
|
+ return { ...this.data };
|
|
|
}
|
|
|
|
|
|
- async save() {
|
|
|
- let method = "POST";
|
|
|
- let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}`;
|
|
|
+ setParseObject(parseObject: Parse.Object<Parse.Attributes>) {
|
|
|
+ this.id = parseObject.id;
|
|
|
+ const data = parseObject.toJSON();
|
|
|
+ this.data = data;
|
|
|
+ this.createdAt = data['createdAt'] ? new Date(data['createdAt']) : undefined;
|
|
|
+ this.updatedAt = data['updatedAt'] ? new Date(data['updatedAt']) : undefined;
|
|
|
+ }
|
|
|
|
|
|
+ async save(): Promise<this> {
|
|
|
+ const parseObject = new Parse.Object(this.className);
|
|
|
if (this.id) {
|
|
|
- url += `/${this.id}`;
|
|
|
- method = "PUT";
|
|
|
+ parseObject.id = this.id;
|
|
|
}
|
|
|
-
|
|
|
- const body = JSON.stringify(this.data);
|
|
|
- const response = await fetch(url, {
|
|
|
- headers: {
|
|
|
- "content-type": "application/json;charset=UTF-8",
|
|
|
- "x-parse-application-id": "dev"
|
|
|
- },
|
|
|
- body: body,
|
|
|
- method: method,
|
|
|
- mode: "cors",
|
|
|
- credentials: "omit"
|
|
|
+ Object.keys(this.data).forEach(key => {
|
|
|
+ parseObject.set(key, this.data[key]);
|
|
|
});
|
|
|
-
|
|
|
- const result = await response?.json();
|
|
|
- if (result?.error) {
|
|
|
- throw new Error(result.error);
|
|
|
- }
|
|
|
- if (result?.objectId) {
|
|
|
- this.id = result?.objectId;
|
|
|
- }
|
|
|
+ const savedObject = await parseObject.save();
|
|
|
+ this.setParseObject(savedObject);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- async destroy() {
|
|
|
- if (!this.id) return;
|
|
|
- const response = await fetch(`http://dev.fmode.cn:1337/parse/classes/${this.className}/${this.id}`, {
|
|
|
- headers: {
|
|
|
- "x-parse-application-id": "dev"
|
|
|
- },
|
|
|
- method: "DELETE",
|
|
|
- mode: "cors",
|
|
|
- credentials: "omit"
|
|
|
- });
|
|
|
-
|
|
|
- const result = await response?.json();
|
|
|
- if (result?.error) {
|
|
|
- throw new Error(result.error);
|
|
|
- }
|
|
|
- this.id = null;
|
|
|
+ async destroy(): Promise<boolean> {
|
|
|
+ if (!this.id) return false;
|
|
|
+ const parseObject = new Parse.Object(this.className);
|
|
|
+ parseObject.id = this.id;
|
|
|
+ await parseObject.destroy();
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
- public setParseObject(obj: Parse.Object) {
|
|
|
- this.parseObject = obj;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export class CloudQuery {
|
|
|
- private whereOptions: Record<string, any> = {};
|
|
|
- private className: string;
|
|
|
-
|
|
|
- constructor(className: string) {
|
|
|
- this.className = className;
|
|
|
- }
|
|
|
-
|
|
|
- equalTo(key: string, value: any): CloudQuery {
|
|
|
- if (!this.whereOptions[key]) {
|
|
|
- this.whereOptions[key] = value;
|
|
|
- }
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- async find() {
|
|
|
- let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}`;
|
|
|
-
|
|
|
- if (Object.keys(this.whereOptions).length > 0) {
|
|
|
- url += `?where=${JSON.stringify(this.whereOptions)}`;
|
|
|
- }
|
|
|
-
|
|
|
- const response = await fetch(url, {
|
|
|
- headers: {
|
|
|
- "x-parse-application-id": "dev"
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- const result = await response?.json();
|
|
|
- return result?.results || [];
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
export class CloudUser extends CloudObject {
|
|
|
@@ -124,113 +63,162 @@ export class CloudUser extends CloudObject {
|
|
|
|
|
|
constructor() {
|
|
|
super('_User');
|
|
|
+ this.restoreFromStorage();
|
|
|
}
|
|
|
|
|
|
- async logIn(username: string, password: string) {
|
|
|
- const response = await fetch(`http://dev.fmode.cn:1337/parse/login`, {
|
|
|
- method: 'POST',
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'application/json',
|
|
|
- 'X-Parse-Application-Id': 'dev'
|
|
|
- },
|
|
|
- body: JSON.stringify({ username, password })
|
|
|
- });
|
|
|
-
|
|
|
- const result = await response.json();
|
|
|
- if (result?.error) {
|
|
|
- throw new Error(result.error);
|
|
|
+ private restoreFromStorage() {
|
|
|
+ const savedUser = localStorage.getItem("NCloud/dev/User");
|
|
|
+ if (savedUser) {
|
|
|
+ try {
|
|
|
+ const userData = JSON.parse(savedUser);
|
|
|
+ this.id = userData.objectId;
|
|
|
+ this.sessionToken = userData.sessionToken;
|
|
|
+ this.data = userData;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Failed to restore user session:', error);
|
|
|
+ localStorage.removeItem("NCloud/dev/User");
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- this.id = result.objectId;
|
|
|
- this.sessionToken = result.sessionToken;
|
|
|
- this.data = result;
|
|
|
- localStorage.setItem("NCloud/dev/User", JSON.stringify(result));
|
|
|
- return this;
|
|
|
}
|
|
|
|
|
|
- async logOut() {
|
|
|
- if (!this.sessionToken) {
|
|
|
- throw new Error('User not logged in');
|
|
|
- }
|
|
|
-
|
|
|
- const response = await fetch(`http://dev.fmode.cn:1337/parse/logout`, {
|
|
|
- headers: {
|
|
|
- 'X-Parse-Application-Id': 'dev',
|
|
|
- 'X-Parse-Session-Token': this.sessionToken
|
|
|
- },
|
|
|
- method: 'POST'
|
|
|
- });
|
|
|
+ async logIn(username: string, password: string) {
|
|
|
+ try {
|
|
|
+ const response = await fetch(`${Parse.serverURL}/login`, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'X-Parse-Application-Id': 'dev',
|
|
|
+ 'X-Parse-Revocable-Session': '1'
|
|
|
+ },
|
|
|
+ body: JSON.stringify({ username, password })
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ const error = await response.json();
|
|
|
+ throw new Error(error.error || '登录失败');
|
|
|
+ }
|
|
|
|
|
|
- const result = await response.json();
|
|
|
- if (result?.error) {
|
|
|
- throw new Error(result.error);
|
|
|
+ const result = await response.json();
|
|
|
+ this.id = result.objectId;
|
|
|
+ this.sessionToken = result.sessionToken;
|
|
|
+ this.data = result;
|
|
|
+ localStorage.setItem("NCloud/dev/User", JSON.stringify(result));
|
|
|
+ return this;
|
|
|
+ } catch (error: any) {
|
|
|
+ console.error('Login failed:', error);
|
|
|
+ throw new Error(error.message || '登录失败');
|
|
|
}
|
|
|
-
|
|
|
- this.id = null;
|
|
|
- this.sessionToken = null;
|
|
|
- this.data = {};
|
|
|
- localStorage.removeItem("NCloud/dev/User");
|
|
|
- return true;
|
|
|
}
|
|
|
|
|
|
async signUp(username: string, password: string, additionalData: Record<string, any> = {}) {
|
|
|
- const userData = {
|
|
|
- username,
|
|
|
- password,
|
|
|
- ...additionalData
|
|
|
- };
|
|
|
-
|
|
|
- const response = await fetch(`http://dev.fmode.cn:1337/parse/users`, {
|
|
|
- headers: {
|
|
|
- "x-parse-application-id": "dev",
|
|
|
- "Content-Type": "application/json"
|
|
|
- },
|
|
|
- body: JSON.stringify(userData),
|
|
|
- method: "POST"
|
|
|
- });
|
|
|
+ try {
|
|
|
+ const userData = {
|
|
|
+ username,
|
|
|
+ password,
|
|
|
+ ...additionalData
|
|
|
+ };
|
|
|
+
|
|
|
+ const response = await fetch(`${Parse.serverURL}/users`, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'X-Parse-Application-Id': 'dev',
|
|
|
+ 'X-Parse-Revocable-Session': '1'
|
|
|
+ },
|
|
|
+ body: JSON.stringify(userData)
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ const error = await response.json();
|
|
|
+ throw new Error(error.error || '注册失败');
|
|
|
+ }
|
|
|
|
|
|
- const result = await response?.json();
|
|
|
- if (result?.error) {
|
|
|
- throw new Error(result.error);
|
|
|
+ const result = await response.json();
|
|
|
+ this.id = result.objectId;
|
|
|
+ this.sessionToken = result.sessionToken;
|
|
|
+ this.data = result;
|
|
|
+ localStorage.setItem("NCloud/dev/User", JSON.stringify(result));
|
|
|
+ return this;
|
|
|
+ } catch (error: any) {
|
|
|
+ console.error('Signup failed:', error);
|
|
|
+ throw new Error(error.message || '注册失败');
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- this.id = result?.objectId;
|
|
|
- this.sessionToken = result?.sessionToken;
|
|
|
- this.data = result;
|
|
|
- localStorage.setItem("NCloud/dev/User", JSON.stringify(result));
|
|
|
- return this;
|
|
|
+ async logOut() {
|
|
|
+ try {
|
|
|
+ if (this.sessionToken) {
|
|
|
+ await fetch(`${Parse.serverURL}/logout`, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'X-Parse-Application-Id': 'dev',
|
|
|
+ 'X-Parse-Session-Token': this.sessionToken
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ this.id = null;
|
|
|
+ this.sessionToken = null;
|
|
|
+ this.data = {};
|
|
|
+ localStorage.removeItem("NCloud/dev/User");
|
|
|
+ return true;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Logout failed:', error);
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
override async save() {
|
|
|
if (!this.id || !this.sessionToken) {
|
|
|
- throw new Error('User not logged in');
|
|
|
+ throw new Error('用户未登录');
|
|
|
}
|
|
|
|
|
|
- let url = `http://dev.fmode.cn:1337/parse/users/${this.id}`;
|
|
|
- let data: any = JSON.parse(JSON.stringify(this.data));
|
|
|
- delete data.createdAt;
|
|
|
- delete data.updatedAt;
|
|
|
- delete data.ACL;
|
|
|
- delete data.objectId;
|
|
|
-
|
|
|
- const response = await fetch(url, {
|
|
|
- headers: {
|
|
|
- "content-type": "application/json;charset=UTF-8",
|
|
|
- "x-parse-application-id": "dev",
|
|
|
- "x-parse-session-token": this.sessionToken
|
|
|
- },
|
|
|
- body: JSON.stringify(data),
|
|
|
- method: "PUT",
|
|
|
- mode: "cors",
|
|
|
- credentials: "omit"
|
|
|
- });
|
|
|
+ try {
|
|
|
+ const { createdAt, updatedAt, ACL, objectId, sessionToken, password, ...data } = this.data;
|
|
|
+
|
|
|
+ const response = await fetch(`${Parse.serverURL}/users/${this.id}`, {
|
|
|
+ method: 'PUT',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'X-Parse-Application-Id': 'dev',
|
|
|
+ 'X-Parse-Session-Token': this.sessionToken
|
|
|
+ },
|
|
|
+ body: JSON.stringify(data)
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ const error = await response.json();
|
|
|
+ throw new Error(error.error || '保存失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = await response.json();
|
|
|
+ this.data = { ...this.data, ...result };
|
|
|
+ localStorage.setItem("NCloud/dev/User", JSON.stringify(this.data));
|
|
|
+ return this;
|
|
|
+ } catch (error: any) {
|
|
|
+ console.error('Save user failed:', error);
|
|
|
+ throw new Error(error.message || '保存失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- const result = await response?.json();
|
|
|
- if (result?.error) {
|
|
|
- throw new Error(result.error);
|
|
|
+ async current(): Promise<CloudUser | null> {
|
|
|
+ if (this.id && this.sessionToken) {
|
|
|
+ return this;
|
|
|
}
|
|
|
|
|
|
- localStorage.setItem("NCloud/dev/User", JSON.stringify(this.data));
|
|
|
- return this;
|
|
|
+ const savedUser = localStorage.getItem("NCloud/dev/User");
|
|
|
+ if (savedUser) {
|
|
|
+ try {
|
|
|
+ const userData = JSON.parse(savedUser);
|
|
|
+ this.id = userData.objectId;
|
|
|
+ this.sessionToken = userData.sessionToken;
|
|
|
+ this.data = userData;
|
|
|
+ return this;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Failed to restore user session:', error);
|
|
|
+ localStorage.removeItem("NCloud/dev/User");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
}
|
|
|
}
|