فهرست منبع

Merge branch 'master' of http://git.fmode.cn:3000/0235656/cloth-design

匡智超 5 روز پیش
والد
کامیت
c4123d25db

+ 5 - 2
cloth-design/angular.json

@@ -13,7 +13,8 @@
       "root": "",
       "sourceRoot": "src",
       "prefix": "app",
-      "architect": {
+      "architect": 
+      {
         "build": {
           "builder": "@angular/build:application",
           "options": {
@@ -73,7 +74,9 @@
         "extract-i18n": {
           "builder": "@angular/build:extract-i18n"
         },
-        "test": {
+
+        "test": 
+        {
           "builder": "@angular/build:karma",
           "options": {
             "polyfills": [

+ 7 - 3
cloth-design/src/app/modules/cloth/mobile/nav-mobile-tabs/nav-mobile-tabs.component.html

@@ -5,10 +5,14 @@
   <div class="tab" [class.active]="activeTab === 'ip'" (click)="changeTab('ip')">
     <i class="fas fa-crown"></i> IP
   </div>
+
+   <div class="tab" [class.active]="activeTab === 'trends'" (click)="changeTab('trends')">
+    <i class="fas fa-chart-line"></i> 趋势
+  </div>
+  
   <div class="tab" [class.active]="activeTab === 'mine'" (click)="changeTab('mine')">
     <i class="fas fa-user"></i> 我的
   </div>
-  <div class="tab" [class.active]="activeTab === 'trends'" (click)="changeTab('trends')">
-    <i class="fas fa-chart-line"></i> 趋势
-  </div>
+
+ 
 </div>

+ 15 - 8
cloth-design/src/app/modules/cloth/mobile/page-trends/page-trends.component.html

@@ -9,14 +9,21 @@
   
   <h3>热门搭配方案</h3>
   <div class="color-stats">
-    @for (combo of popularCombinations; track combo.name) {
-      <div class="color-stat">
-        <div class="color-box" [style]="getGradientStyle(combo.colors)">
-          <i [class]="combo.icon"></i>
-        </div>
-        <div class="stat-name">{{ combo.name }}</div>
-        <div class="stat-count">{{ combo.count }}</div>
+    
+    <div class="color-stat">
+      <div class="color-box" style="background: linear-gradient(135deg, #3498db, #2c3e50);">
+        <i class="fas fa-water"></i>
       </div>
-    }
+      <div class="stat-name">深海蓝黑</div>
+      <div class="stat-count">5,678 次使用</div>
+    </div>
+
+    <div class="color-stat">
+      <div class="color-box" style="background: linear-gradient(135deg, #e74c3c, #f1c40f);">
+        <i class="fas fa-sun"></i>
+      </div>
+      <div class="stat-name">日落橙黄</div>
+      <div class="stat-count">4,987 次使用</div>
+    </div>
   </div>
 </div>

+ 431 - 0
cloth-design/src/lib/ncloud.ts

@@ -0,0 +1,431 @@
+// CloudObject.ts
+
+let serverURL = `https://dev.fmode.cn/parse`;
+if (location.protocol == "http:") {
+    serverURL = `http://dev.fmode.cn:1337/parse`;
+}
+
+export class CloudObject {
+    className: string;
+    id: string | undefined = undefined;
+    createdAt: any;
+    updatedAt: any;
+    data: Record<string, any> = {};
+
+    constructor(className: string) {
+        this.className = className;
+    }
+
+    toPointer() {
+        return { "__type": "Pointer", "className": this.className, "objectId": this.id };
+    }
+
+    set(json: Record<string, any>) {
+        Object.keys(json).forEach(key => {
+            if (["objectId", "id", "createdAt", "updatedAt"].indexOf(key) > -1) {
+                return;
+            }
+            this.data[key] = json[key];
+        });
+    }
+
+    get(key: string) {
+        return this.data[key] || null;
+    }
+
+    async save() {
+        let method = "POST";
+        let url = serverURL + `/classes/${this.className}`;
+
+        // 更新
+        if (this.id) {
+            url += `/${this.id}`;
+            method = "PUT";
+        }
+
+        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"
+        });
+
+        const result = await response?.json();
+        if (result?.error) {
+            console.error(result?.error);
+        }
+        if (result?.objectId) {
+            this.id = result?.objectId;
+        }
+        return this;
+    }
+
+    async destroy() {
+        if (!this.id) return;
+        const response = await fetch(serverURL + `/classes/${this.className}/${this.id}`, {
+            headers: {
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "DELETE",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const result = await response?.json();
+        if (result) {
+            this.id = undefined;
+        }
+        return true;
+    }
+}
+
+// CloudQuery.ts
+export class CloudQuery {
+    className: string;
+    queryParams: Record<string, any> = { where: {} };
+
+    constructor(className: string) {
+        this.className = className;
+    }
+
+    include(...fileds: string[]) {
+        this.queryParams["include"] = fileds;
+    }
+    greaterThan(key: string, value: any) {
+        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
+        this.queryParams["where"][key]["$gt"] = value;
+    }
+
+    greaterThanAndEqualTo(key: string, value: any) {
+        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
+        this.queryParams["where"][key]["$gte"] = value;
+    }
+
+    lessThan(key: string, value: any) {
+        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
+        this.queryParams["where"][key]["$lt"] = value;
+    }
+
+    lessThanAndEqualTo(key: string, value: any) {
+        if (!this.queryParams["where"][key]) this.queryParams["where"][key] = {};
+        this.queryParams["where"][key]["$lte"] = value;
+    }
+
+    equalTo(key: string, value: any) {
+        if (!this.queryParams["where"]) this.queryParams["where"] = {};
+        this.queryParams["where"][key] = value;
+    }
+
+    async get(id: string) {
+        const url = serverURL + `/classes/${this.className}/${id}?`;
+
+        const response = await fetch(url, {
+            headers: {
+                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "GET",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const json = await response?.json();
+        if (json) {
+            let existsObject = this.dataToObj(json)
+            return existsObject;
+        }
+        return null
+    }
+
+    async find(): Promise<Array<CloudObject>> {
+        let url = serverURL + `/classes/${this.className}?`;
+
+        let queryStr = ``
+        Object.keys(this.queryParams).forEach(key => {
+            let paramStr = JSON.stringify(this.queryParams[key]);
+            if (key == "include") {
+                paramStr = this.queryParams[key]?.join(",")
+            }
+            if (queryStr) {
+                url += `${key}=${paramStr}`;
+            } else {
+                url += `&${key}=${paramStr}`;
+            }
+        })
+        // if (Object.keys(this.queryParams["where"]).length) {
+
+        // }
+
+        const response = await fetch(url, {
+            headers: {
+                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "GET",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const json = await response?.json();
+        let list = json?.results || []
+        let objList = list.map((item: any) => this.dataToObj(item))
+        return objList || [];
+    }
+
+
+    async first() {
+        let url = serverURL + `/classes/${this.className}?`;
+
+        if (Object.keys(this.queryParams["where"]).length) {
+            const whereStr = JSON.stringify(this.queryParams["where"]);
+            url += `where=${whereStr}&limit=1`;
+        }
+
+        const response = await fetch(url, {
+            headers: {
+                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "GET",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const json = await response?.json();
+        const exists = json?.results?.[0] || null;
+        if (exists) {
+            let existsObject = this.dataToObj(exists)
+            return existsObject;
+        }
+        return null
+    }
+
+    dataToObj(exists: any): CloudObject {
+        let existsObject = new CloudObject(this.className);
+        Object.keys(exists).forEach(key => {
+            if (exists[key]?.__type == "Object") {
+                exists[key] = this.dataToObj(exists[key])
+            }
+        })
+        existsObject.set(exists);
+        existsObject.id = exists.objectId;
+        existsObject.createdAt = exists.createdAt;
+        existsObject.updatedAt = exists.updatedAt;
+        return existsObject;
+    }
+}
+
+// CloudUser.ts
+export class CloudUser extends CloudObject {
+    constructor() {
+        super("_User"); // 假设用户类在Parse中是"_User"
+        // 读取用户缓存信息
+        let userCacheStr = localStorage.getItem("NCloud/dev/User")
+        if (userCacheStr) {
+            let userData = JSON.parse(userCacheStr)
+            // 设置用户信息
+            this.id = userData?.objectId;
+            this.sessionToken = userData?.sessionToken;
+            this.data = userData; // 保存用户数据
+        }
+    }
+
+    sessionToken: string | null = ""
+    /** 获取当前用户信息 */
+    async current() {
+        if (!this.sessionToken) {
+            console.error("用户未登录");
+            return null;
+        }
+        return this;
+        // const response = await fetch(serverURL + `/users/me`, {
+        //     headers: {
+        //         "x-parse-application-id": "dev",
+        //         "x-parse-session-token": this.sessionToken // 使用sessionToken进行身份验证
+        //     },
+        //     method: "GET"
+        // });
+
+        // const result = await response?.json();
+        // if (result?.error) {
+        //     console.error(result?.error);
+        //     return null;
+        // }
+        // return result;
+    }
+
+    /** 登录 */
+    async login(username: string, password: string): Promise<CloudUser | null> {
+        const response = await fetch(serverURL + `/login`, {
+            headers: {
+                "x-parse-application-id": "dev",
+                "Content-Type": "application/json"
+            },
+            body: JSON.stringify({ username, password }),
+            method: "POST"
+        });
+
+        const result = await response?.json();
+        if (result?.error) {
+            console.error(result?.error);
+            return null;
+        }
+
+        // 设置用户信息
+        this.id = result?.objectId;
+        this.sessionToken = result?.sessionToken;
+        this.data = result; // 保存用户数据
+        // 缓存用户信息
+        console.log(result)
+        localStorage.setItem("NCloud/dev/User", JSON.stringify(result))
+        return this;
+    }
+
+    /** 登出 */
+    async logout() {
+        if (!this.sessionToken) {
+            console.error("用户未登录");
+            return;
+        }
+
+        const response = await fetch(serverURL + `/logout`, {
+            headers: {
+                "x-parse-application-id": "dev",
+                "x-parse-session-token": this.sessionToken
+            },
+            method: "POST"
+        });
+
+        let result = await response?.json();
+
+        if (result?.error) {
+            console.error(result?.error);
+            if (result?.error == "Invalid session token") {
+                this.clearUserCache()
+                return true;
+            }
+            return false;
+        }
+
+        this.clearUserCache()
+        return true;
+    }
+    clearUserCache() {
+        // 清除用户信息
+        localStorage.removeItem("NCloud/dev/User")
+        this.id = undefined;
+        this.sessionToken = null;
+        this.data = {};
+    }
+
+    /** 注册 */
+    async signUp(username: string, password: string, additionalData: Record<string, any> = {}) {
+        const userData = {
+            username,
+            password,
+            ...additionalData // 合并额外的用户数据
+        };
+
+        const response = await fetch(serverURL + `/users`, {
+            headers: {
+                "x-parse-application-id": "dev",
+                "Content-Type": "application/json"
+            },
+            body: JSON.stringify(userData),
+            method: "POST"
+        });
+
+        const result = await response?.json();
+        if (result?.error) {
+            console.error(result?.error);
+            return null;
+        }
+
+        // 设置用户信息
+        // 缓存用户信息
+        console.log(result)
+        localStorage.setItem("NCloud/dev/User", JSON.stringify(result))
+        this.id = result?.objectId;
+        this.sessionToken = result?.sessionToken;
+        this.data = result; // 保存用户数据
+        return this;
+    }
+
+    override async save() {
+        let method = "POST";
+        let url = serverURL + `/users`;
+
+        // 更新用户信息
+        if (this.id) {
+            url += `/${this.id}`;
+            method = "PUT";
+        }
+
+        let data: any = JSON.parse(JSON.stringify(this.data))
+        delete data.createdAt
+        delete data.updatedAt
+        delete data.ACL
+        delete data.objectId
+        const body = JSON.stringify(data);
+        let headersOptions: any = {
+            "content-type": "application/json;charset=UTF-8",
+            "x-parse-application-id": "dev",
+            "x-parse-session-token": this.sessionToken, // 添加sessionToken以进行身份验证
+        }
+        const response = await fetch(url, {
+            headers: headersOptions,
+            body: body,
+            method: method,
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const result = await response?.json();
+        if (result?.error) {
+            console.error(result?.error);
+        }
+        if (result?.objectId) {
+            this.id = result?.objectId;
+        }
+        localStorage.setItem("NCloud/dev/User", JSON.stringify(this.data))
+        return this;
+    }
+}
+
+export class CloudApi {
+    async fetch(path: string, body: any, options?: {
+        method: string
+        body: any
+    }) {
+
+        let reqOpts: any = {
+            headers: {
+                "x-parse-application-id": "dev",
+                "Content-Type": "application/json"
+            },
+            method: options?.method || "POST",
+            mode: "cors",
+            credentials: "omit"
+        }
+        if (body || options?.body) {
+            reqOpts.body = JSON.stringify(body || options?.body);
+            reqOpts.json = true;
+        }
+        let host = `https://dev.fmode.cn`
+        // host = `http://127.0.0.1:1337`
+        let url = `${host}/api/` + path
+        console.log(url, reqOpts)
+        const response = await fetch(url, reqOpts);
+        let json = await response.json();
+        return json
+    }
+}