ncloud.ts 13 KB

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