ncloud.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. import * as Parse from 'parse';
  2. // CloudObject.ts
  3. export class CloudObject {
  4. className: string;
  5. id: string | null = null;
  6. createdAt: any;
  7. updatedAt: any;
  8. data: Record<string, any> = {};
  9. constructor(className: string) {
  10. this.className = className;
  11. }
  12. toPointer() {
  13. return { "__type": "Pointer", "className": this.className, "objectId": this.id };
  14. }
  15. set(json: Record<string, any>) {
  16. Object.keys(json).forEach(key => {
  17. if (["objectId", "id", "createdAt", "updatedAt", "ACL"].indexOf(key) > -1) {
  18. if (key === "objectId") this.id = json[key];
  19. return;
  20. }
  21. this.data[key] = json[key];
  22. });
  23. }
  24. get(key: string) {
  25. return this.data[key] || null;
  26. }
  27. async save() {
  28. let method = "POST";
  29. let url = `https://dev.fmode.cn/parse/classes/${this.className}`;
  30. if (this.id) {
  31. url += `/${this.id}`;
  32. method = "PUT";
  33. }
  34. const body = JSON.stringify(this.data);
  35. const response = await fetch(url, {
  36. headers: {
  37. "content-type": "application/json;charset=UTF-8",
  38. "x-parse-application-id": "dev"
  39. },
  40. body: body,
  41. method: method,
  42. mode: "cors",
  43. credentials: "omit"
  44. });
  45. const result = await response?.json();
  46. if (result?.error) {
  47. throw new Error(result.error);
  48. }
  49. if (result?.objectId) {
  50. this.id = result?.objectId;
  51. }
  52. return this;
  53. }
  54. async destroy() {
  55. if (!this.id) return;
  56. const response = await fetch(`https://dev.fmode.cn/parse/classes/${this.className}/${this.id}`, {
  57. headers: {
  58. "x-parse-application-id": "dev"
  59. },
  60. method: "DELETE",
  61. mode: "cors",
  62. credentials: "omit"
  63. });
  64. const result = await response?.json();
  65. if (result?.error) {
  66. throw new Error(result.error);
  67. }
  68. this.id = null;
  69. return true;
  70. }
  71. protected setParseObject(obj: Parse.Object) {
  72. this.parseObject = obj;
  73. }
  74. }
  75. export class CloudQuery {
  76. private query: Parse.Query;
  77. className: string;
  78. queryParams: Record<string, any> = {};
  79. constructor(className: string) {
  80. this.className = className;
  81. }
  82. // 作用是将查询参数转换为对象
  83. include(...fileds:string[]) {
  84. this.queryParams["include"] = fileds;
  85. }
  86. greaterThan(key: string, value: any) {
  87. if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
  88. this.queryParams["where"][key]["$gt"] = value;
  89. }
  90. greaterThanAndEqualTo(key: string, value: any) {
  91. if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
  92. this.queryParams["where"][key]["$gte"] = value;
  93. }
  94. lessThan(key: string, value: any) {
  95. if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
  96. this.queryParams["where"][key]["$lt"] = value;
  97. }
  98. lessThanAndEqualTo(key: string, value: any) {
  99. if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
  100. this.queryParams["where"][key]["$lte"] = value;
  101. }
  102. equalTo(key: string, value: any) {
  103. this.queryParams["where"][key] = value;
  104. }
  105. async get(id: string) {
  106. const url = `http://dev.fmode.cn:1337/parse/classes/${this.className}/${id}?`;
  107. const response = await fetch(url, {
  108. headers: {
  109. "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
  110. "x-parse-application-id": "dev"
  111. },
  112. body: null,
  113. method: "GET",
  114. mode: "cors",
  115. credentials: "omit"
  116. });
  117. const json = await response?.json();
  118. // return json || {};
  119. const exists = json?.results?.[0] || null;
  120. if (exists) {
  121. let existsObject = this.dataToObj(exists)
  122. return existsObject;
  123. }
  124. return null
  125. }
  126. async find(): Promise<CloudObject[]> {
  127. try {
  128. const results = await this.query.find();
  129. return results.map((result: Parse.Object) => {
  130. const obj = new CloudObject(this.className);
  131. (obj as any).parseObject = result; // 使用类型断言
  132. return obj;
  133. });
  134. } catch (error) {
  135. console.error('Query failed:', error);
  136. throw error;
  137. }
  138. }
  139. async first() {
  140. let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}?`;
  141. if (Object.keys(this.queryParams["where"]).length) {
  142. const whereStr = JSON.stringify(this.queryParams["where"]);
  143. url += `where=${whereStr}`;
  144. }
  145. const response = await fetch(url, {
  146. headers: {
  147. "x-parse-application-id": "dev"
  148. }
  149. });
  150. const json = await response?.json();
  151. // const exists = json?.results?.[0] || null;
  152. // if (exists) {
  153. // let existsObject = this.dataToObj(exists)
  154. // return existsObject;
  155. // }
  156. // return null
  157. let list = json?.results || []
  158. let objList = list.map((item:any)=>this.dataToObj(item))
  159. return objList || [];
  160. }
  161. }
  162. export class CloudUser extends CloudObject {
  163. sessionToken: string | null = null;
  164. constructor() {
  165. super("_User"); // 假设用户类在Parse中是"_User"
  166. // 读取用户缓存信息
  167. let userCacheStr = localStorage.getItem("NCloud/dev/User")
  168. if(userCacheStr){
  169. let userData = JSON.parse(userCacheStr)
  170. // 设置用户信息
  171. this.id = userData?.objectId;
  172. this.sessionToken = userData?.sessionToken;
  173. this.data = userData; // 保存用户数据
  174. }
  175. }
  176. sessionToken:string|null = ""
  177. /** 获取当前用户信息 */
  178. async current() {
  179. if (!this.sessionToken) {
  180. console.error("用户未登录");
  181. return null;
  182. }
  183. return this;
  184. // const response = await fetch(`http://dev.fmode.cn:1337/parse/users/me`, {
  185. // headers: {
  186. // "x-parse-application-id": "dev",
  187. // "x-parse-session-token": this.sessionToken // 使用sessionToken进行身份验证
  188. // },
  189. // method: "GET"
  190. // });
  191. // const result = await response?.json();
  192. // if (result?.error) {
  193. // console.error(result?.error);
  194. // return null;
  195. // }
  196. // return result;
  197. }
  198. /** 登录 */
  199. async login(username: string, password: string):Promise<CloudUser|null> {
  200. const response = await fetch(`http://dev.fmode.cn:1337/parse/login`, {
  201. headers: {
  202. 'Content-Type': 'application/json',
  203. 'X-Parse-Application-Id': 'dev'
  204. },
  205. body: JSON.stringify({ username, password })
  206. });
  207. const result = await response.json();
  208. if (result?.error) {
  209. throw new Error(result.error);
  210. }
  211. this.id = result.objectId;
  212. this.sessionToken = result.sessionToken;
  213. this.data = result;
  214. localStorage.setItem("NCloud/dev/User", JSON.stringify(result));
  215. return this;
  216. }
  217. async logOut() {
  218. if (!this.sessionToken) {
  219. throw new Error('User not logged in');
  220. }
  221. const response = await fetch(`https://dev.fmode.cn/parse/logout`, {
  222. headers: {
  223. 'X-Parse-Application-Id': 'dev',
  224. 'X-Parse-Session-Token': this.sessionToken
  225. },
  226. method: 'POST'
  227. });
  228. const result = await response?.json();
  229. if (result?.error) {
  230. console.error(result?.error);
  231. return false;
  232. }
  233. // 清除用户信息
  234. localStorage.removeItem("NCloud/dev/User")
  235. this.id = null;
  236. this.sessionToken = null;
  237. this.data = {};
  238. return true;
  239. }
  240. async signUp(username: string, password: string, additionalData: Record<string, any> = {}) {
  241. const userData = {
  242. username,
  243. password,
  244. ...additionalData // 合并额外的用户��据
  245. };
  246. const response = await fetch(`https://dev.fmode.cn/parse/users`, {
  247. headers: {
  248. "x-parse-application-id": "dev",
  249. "Content-Type": "application/json"
  250. },
  251. body: JSON.stringify(userData),
  252. method: "POST"
  253. });
  254. const result = await response?.json();
  255. if (result?.error) {
  256. throw new Error(result.error);
  257. }
  258. this.id = result?.objectId;
  259. this.sessionToken = result?.sessionToken;
  260. this.data = result;
  261. localStorage.setItem("NCloud/dev/User", JSON.stringify(result));
  262. return this;
  263. }
  264. override async save() {
  265. let method = "POST";
  266. let url = `http://dev.fmode.cn:1337/parse/users`;
  267. // 更新用户信息
  268. if (this.id) {
  269. url += `/${this.id}`;
  270. method = "PUT";
  271. }
  272. let data:any = JSON.parse(JSON.stringify(this.data))
  273. delete data.createdAt
  274. delete data.updatedAt
  275. delete data.ACL
  276. delete data.objectId
  277. const body = JSON.stringify(data);
  278. let headersOptions:any = {
  279. "content-type": "application/json;charset=UTF-8",
  280. "x-parse-application-id": "dev",
  281. "x-parse-session-token": this.sessionToken, // 添加sessionToken以进行身份验证
  282. }
  283. const response = await fetch(url, {
  284. headers: {
  285. "content-type": "application/json;charset=UTF-8",
  286. "x-parse-application-id": "dev",
  287. "x-parse-session-token": this.sessionToken
  288. },
  289. body: JSON.stringify(data),
  290. method: "PUT",
  291. mode: "cors",
  292. credentials: "omit"
  293. });
  294. const result = await response?.json();
  295. if (result?.error) {
  296. throw new Error(result.error);
  297. }
  298. localStorage.setItem("NCloud/dev/User", JSON.stringify(this.data));
  299. return this;
  300. }
  301. }
  302. export class CloudApi{
  303. async fetch(path:string,body:any,options?:{
  304. method:string
  305. body:any
  306. }){
  307. let reqOpts:any = {
  308. headers: {
  309. "x-parse-application-id": "dev",
  310. "Content-Type": "application/json"
  311. },
  312. method: options?.method || "POST",
  313. mode: "cors",
  314. credentials: "omit"
  315. }
  316. if(body||options?.body){
  317. reqOpts.body = JSON.stringify(body || options?.body);
  318. reqOpts.json = true;
  319. }
  320. let host = `https://dev.fmode.cn`
  321. // host = `http://127.0.0.1:1337`
  322. let url = `${host}/api/`+path
  323. console.log(url,reqOpts)
  324. const response = await fetch(url,reqOpts);
  325. let json = await response.json();
  326. return json
  327. }
  328. }