ncloud.ts 12 KB

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