Browse Source

Merge branch 'master' into LMF

城南花开 11 tháng trước cách đây
mục cha
commit
ae320d2854
39 tập tin đã thay đổi với 2222 bổ sung162 xóa
  1. 637 71
      tailor-app/myapp/package-lock.json
  2. 8 0
      tailor-app/myapp/package.json
  3. 38 9
      tailor-app/myapp/src/app/community/community.page.html
  4. 30 0
      tailor-app/myapp/src/app/community/community.page.scss
  5. 22 5
      tailor-app/myapp/src/app/community/community.page.ts
  6. 50 5
      tailor-app/myapp/src/app/customization/customization.page.html
  7. 173 4
      tailor-app/myapp/src/app/customization/customization.page.ts
  8. 99 0
      tailor-app/myapp/src/app/customization/test-chat-completion.ts
  9. 11 0
      tailor-app/myapp/src/app/edit-tag/edit-tag.component.html
  10. 0 0
      tailor-app/myapp/src/app/edit-tag/edit-tag.component.scss
  11. 24 0
      tailor-app/myapp/src/app/edit-tag/edit-tag.component.spec.ts
  12. 43 0
      tailor-app/myapp/src/app/edit-tag/edit-tag.component.ts
  13. BIN
      tailor-app/myapp/src/app/me/img/绘图1.jpg
  14. 233 7
      tailor-app/myapp/src/app/me/me.page.html
  15. 109 5
      tailor-app/myapp/src/app/me/me.page.ts
  16. 99 0
      tailor-app/myapp/src/app/me/test-chat-completion.ts
  17. 3 0
      tailor-app/myapp/src/app/module/slide/slide.component.html
  18. 0 0
      tailor-app/myapp/src/app/module/slide/slide.component.scss
  19. 24 0
      tailor-app/myapp/src/app/module/slide/slide.component.spec.ts
  20. 14 0
      tailor-app/myapp/src/app/module/slide/slide.component.ts
  21. 13 0
      tailor-app/myapp/src/app/module/slide/slide.module.ts
  22. 32 12
      tailor-app/myapp/src/app/store/store.page.html
  23. 38 0
      tailor-app/myapp/src/app/store/store.page.scss
  24. 229 3
      tailor-app/myapp/src/app/store/store.page.ts
  25. 1 1
      tailor-app/myapp/src/app/tabs/tabs.page.html
  26. 3 0
      tailor-app/myapp/src/app/tabs/tabs.page.scss
  27. 167 9
      tailor-app/myapp/src/app/yiyun/yiyun.page.html
  28. 77 0
      tailor-app/myapp/src/app/yiyun/yiyun.page.scss
  29. 29 29
      tailor-app/myapp/src/app/yiyun/yiyun.page.ts
  30. BIN
      tailor-app/myapp/src/assets/img/3d.png
  31. BIN
      tailor-app/myapp/src/assets/img/ai2.png
  32. BIN
      tailor-app/myapp/src/assets/img/ding.png
  33. BIN
      tailor-app/myapp/src/assets/img/ding2.png
  34. BIN
      tailor-app/myapp/src/assets/img/jj.png
  35. BIN
      tailor-app/myapp/src/assets/img/shi.png
  36. BIN
      tailor-app/myapp/src/assets/img/yi2.png
  37. 14 1
      tailor-app/myapp/src/main.ts
  38. 2 1
      tailor-app/myapp/tsconfig.json
  39. BIN
      tailor-prod/衣韵智裁项目开题演讲.pptx

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 637 - 71
tailor-app/myapp/package-lock.json


+ 8 - 0
tailor-app/myapp/package.json

@@ -27,9 +27,17 @@
     "@capacitor/keyboard": "6.0.3",
     "@capacitor/status-bar": "6.0.2",
     "@ionic/angular": "^8.0.0",
+    "@ionic/vue": "^8.4.0",
+    "@ionic/vue-router": "^8.4.0",
+    "@types/echarts": "^4.9.22",
+    "echarts": "^5.5.1",
+    "fmode-ng": "^0.0.62",
     "ionicons": "^7.2.1",
+    "parse": "^5.3.0",
     "rxjs": "~7.8.0",
+    "swiper": "^11.1.15",
     "tslib": "^2.3.0",
+    "vue": "^3.5.13",
     "zone.js": "~0.14.2"
   },
   "devDependencies": {

+ 38 - 9
tailor-app/myapp/src/app/community/community.page.html

@@ -1,13 +1,42 @@
-<ion-header [translucent]="true">
+<ion-header>
   <ion-toolbar>
-    <ion-title>community</ion-title>
+    <ion-title>
+      帖子
+    </ion-title>
   </ion-toolbar>
 </ion-header>
+ 
+<ion-content>
+  <div class="waterfall">
+    <div class="post-item" style="position: relative;">
+      <img src="assets/img/jj.png" alt="Post Image" class="img" />
+      <h3> post.title </h3>
+      <p> post.content</p>
+      <ion-chip style="margin: 0;">
+        <ion-avatar>
+          <img alt="Silhouette of a person's head" src="https://ionicframework.com/docs/img/demos/avatar.svg" />
+        </ion-avatar>
+        <ion-label>Chip Avatar</ion-label>
+      </ion-chip>
+      <div style="display: flex; align-items: center;position: absolute;bottom: 15px;right: 15px;">
+        <ion-icon name="heart" style="font-size: 16px;"></ion-icon>
+        <span style="margin-left: 4px;font-size: 16px;">11</span>
+      </div>
+        
+    </div>
+    <div class="post-item" style="">
+      <img src="assets/img/shi.png" alt="Post Image" />
+      <h3> post.title </h3>
+      <p> post.content</p>
+    </div>
+    <div class="post-item" style="">
+      <img src="assets/img/shi.png" alt="Post Image" />
+      <h3> post.title </h3>
+      <p> post.content</p>
+    </div>
+    
 
-<ion-content [fullscreen]="true">
-  <ion-header collapse="condense">
-    <ion-toolbar>
-      <ion-title size="large">community</ion-title>
-    </ion-toolbar>
-  </ion-header>
-</ion-content>
+    
+  </div>
+  
+</ion-content>

+ 30 - 0
tailor-app/myapp/src/app/community/community.page.scss

@@ -0,0 +1,30 @@
+/* src/pages/posts/posts.page.scss */
+.waterfall {
+    column-count: 2; // 设置列数
+    column-gap: 16px; // 设置列间距
+    width: 100%;
+  }
+  
+  .post-item {
+    break-inside: avoid; // 防止内容在列中拆分
+    margin-bottom: 16px; // 设置项目间距
+    padding: 8px;
+    background: #fff;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    border-radius: 8px;
+  }
+  
+  .img {
+    width: 100%;
+    height: auto;
+    border-radius: 8px 8px 0 0;
+  }
+  
+  .post-item h3 {
+    margin: 16px 0 8px;
+  }
+  
+  .post-item p {
+    color: #666;
+  }
+  

+ 22 - 5
tailor-app/myapp/src/app/community/community.page.ts

@@ -1,20 +1,37 @@
-import { Component, OnInit } from '@angular/core';
+
+import { Component, NgModule, OnInit } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
-import { IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { addIcons } from 'ionicons';
+import { camera,trendingUpOutline,sparklesOutline,cloudyOutline,diceOutline,heart,heartOutline} from 'ionicons/icons';
+import { IonContent, IonHeader, IonTitle, IonToolbar, IonButton, IonLabel, IonItem, IonList, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemOption, IonItemSliding, IonInput, IonCheckbox, IonRadio, IonToggle, IonRadioGroup, IonSearchbar,IonSegment,IonSegmentButton,IonDatetime,IonFooter,IonCardContent,IonCardTitle,IonCardHeader,IonCard,IonCol,IonRow,IonGrid,IonChip,IonTabButton,IonListHeader,ItemReorderEventDetail, IonTabBar, IonTabs,IonCardSubtitle,IonImg,IonBadge   } from '@ionic/angular/standalone';
+addIcons({camera,trendingUpOutline,sparklesOutline,cloudyOutline,diceOutline,heart,heartOutline})
 
+import * as echarts from 'echarts';
 @Component({
   selector: 'app-community',
   templateUrl: './community.page.html',
   styleUrls: ['./community.page.scss'],
   standalone: true,
-  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule]
+  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule, IonButton,  IonLabel, IonLabel, IonList, IonItem, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemSliding, IonItemOption, IonItemOptions,IonInput,IonCheckbox,IonRadio,IonToggle,IonRadioGroup,IonSearchbar,IonSegment,IonSegmentButton,IonDatetime,IonFooter,IonCardContent,IonCardTitle,IonCardHeader,IonCard,IonCol,IonRow,IonGrid,IonChip,IonTabButton,IonTabBar,IonTabs,IonListHeader,IonCardSubtitle,IonImg,IonBadge ]
+
 })
-export class CommunityPage implements OnInit {
 
+
+export class CommunityPage implements OnInit {
+  public  posts = [
+    { imageUrl: 'assets/img/shi.png', title: 'title', content: 'content' },
+    { imageUrl: 'assets/img/shi.png', title: 'title', content: 'content' },
+   
+    
+  ];
+  
   constructor() { }
 
   ngOnInit() {
+    
+    
   }
-
+  
 }
+

+ 50 - 5
tailor-app/myapp/src/app/customization/customization.page.html

@@ -5,9 +5,54 @@
 </ion-header>
 
 <ion-content [fullscreen]="true">
-  <ion-header collapse="condense">
-    <ion-toolbar>
-      <ion-title size="large">customization</ion-title>
-    </ion-toolbar>
-  </ion-header>
+  
+  
+
+
+    <ion-list >
+      <ion-item  >
+        <app-edit-tag (onTagChange)="setTags($event)"></app-edit-tag>
+      </ion-item>
+
+      <ion-item  >
+        <ion-textarea (ionInput)="onInputarea($event)" label="服装描述" placeholder="请尽可能描述衣服需要的功能" [autoGrow]="true"></ion-textarea>
+      </ion-item>
+
+    </ion-list>    
+    <!-- <h1>父级页面传参</h1>
+    @for(tag of editTags;track tag;){
+      <p>{{tag}}</p>
+    } -->
+    <!-- GPT组件 -->
+    <!-- <h1>GPT组件</h1>
+     <ion-input type="" [(ngModel)]="inputValue"  ></ion-input> -->
+    <ion-button (click)="printInputValue()">提交</ion-button>
+    @if(!isComplete){
+      <div>{{gptre}}</div>
+    }
+   
+   @if(isComplete){
+    <fm-markdown-preview class="content-style" [content]="gptre" ></fm-markdown-preview>
+   }
+
+
+   <ion-title>服装生成{{imagineWork?.progress || 0}}</ion-title>
+   <!-- <ion-textarea [value]="userPrompt" (ionInput)="promptInput($event)" placeholder="服装填写" autoGrow="true"></ion-textarea> -->
+  <ion-button (click)="createImage()" expand="block">生成图片</ion-button>
+  <!-- 生成结果 -->
+  @if(images.length) {
+    @for(imageUrl of images;track imageUrl){
+      <img [src]="imageUrl" alt="" srcset="">
+    }
+  }
+  <!-- 生成状态 -->
+  @if(!images.length){
+    @if(imagineWork){
+      <h1>生成中</h1>
+    }
+    @if(!imagineWork){
+      <h1>未开始</h1>
+    }
+  }
+  {{   picdetail}}
 </ion-content>

+ 173 - 4
tailor-app/myapp/src/app/customization/customization.page.ts

@@ -1,20 +1,189 @@
 import { Component, OnInit } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
-import { IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
-
+import { IonContent, IonHeader, IonTitle, IonToolbar, IonButton, IonInput, IonTextarea, IonItem, IonList } from '@ionic/angular/standalone';
+import { TestChatCompletion } from './test-chat-completion';
+import { EditTagComponent } from '../edit-tag/edit-tag.component';
+import { FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
+import { DalleOptions, ImagineWork } from 'fmode-ng';
 @Component({
   selector: 'app-customization',
   templateUrl: './customization.page.html',
   styleUrls: ['./customization.page.scss'],
   standalone: true,
-  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule]
+  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule, IonButton, IonInput, EditTagComponent, IonTextarea, IonItem, IonList, MarkdownPreviewModule,]
 })
 export class CustomizationPage implements OnInit {
+  public isComplete: boolean = false;
+  public inputValue = ""
+  public gptre = ""
+  area: string = ""
+  editTags: Array<string> = []
+  onInput(event: any) {
+    console.log(event.detail.value);
 
-  constructor() { }
+  }
+  setTags(ev: any) {
+    console.log(ev);
+    this.editTags = ev
+  }
+  onInputarea(event: any) {
+    this.area = event.detail.value;
+    console.log(this.area);
 
+  }
   ngOnInit() {
   }
 
+
+  async printInputValue() {
+    console.log("create")
+    let promt = `您作为一名专业的服装推荐师,请帮我推荐具体的某件衣服,不要鞋子裤子,帽子,我只要你推荐某个具体服装,风格是:${this.editTags.join(",")},需要的衣服功能是:${this.area}`
+    let completion = new FmodeChatCompletion([
+      { role: "system", content: "" },
+      { role: "user", content: promt }
+    ])
+    completion.sendCompletion().subscribe((message: any) => {
+      // 打印消息体
+      console.log(message.content)
+      // 赋值消息内容给组件内属性
+      this.gptre = message.content
+      if (message?.complete) {
+        this.isComplete = true
+      }
+    })
+
+
+
+
+
+
+
+
+    // console.log("开始解析");
+    // console.log(this.inputValue);
+
+    // let token = "r:16cd8f27084ff647fcdb5308a6783c4c"
+    // localStorage.setItem("token",token)
+    // let promt=`您作为一名专业的服装推荐师,请帮我推荐具体的某件衣服,风格是:${this.editTags.join(",")},需要的衣服功能是:${this.area}`
+    // let messageList: any = [
+    //   {
+    //     role: "system", content: `${new Date().toLocaleString}`
+    //   },
+    //   {
+    //     role: "user", content: promt
+    //   }
+    // ]
+
+    // let completion=new TestChatCompletion(messageList)
+    // completion.createCompletionByStream()
+    // setInterval(()=>{
+    //   console.log(messageList);
+    //   if(messageList.length!=1){
+    //     this.gptre=messageList[messageList.length-1].content
+
+    //   }
+    // },2000)
+
+
+    // let bodyJson = {
+    //   "token": `Bearer ${token}`,
+    //   "messages": messageList,
+    //   "model": "fmode-4.5-128k",
+    //   "temperature": 0.5,
+    //   "presence_penalty": 0,
+    //   "frequency_penalty": 0,
+    //   "top_p": 1,
+    //   "stream": true
+    // };
+
+    // let response = await fetch("https://test.fmode.cn/api/apig/aigc/gpt/v1/chat/completions", {
+    //   "headers": {
+    //     "accept": "text/event-stream",
+    //   },
+    //   "body": JSON.stringify(bodyJson),
+    //   "method": "POST",
+    //   "mode": "cors",
+    //   "credentials": "omit"
+    // });
+    // let reader = response.body?.getReader()
+    // if (!reader) {
+    //   throw new Error("Failed to get the response reader.");
+    // }
+
+    // let decoder = new TextDecoder();
+    // let buffer = "";
+
+    // while (true) {
+    //   let { done, value } = await reader.read();
+    //   if (done) {
+    //     break;
+    //   }
+    //   let data = decoder.decode(value);
+    //   let messages = data.split("\n");
+    //   console.log(messages);
+
+    //   for (let i = 0; i < messages.length - 1; i++) {
+    //     let message = messages[i];
+    //     console.log(message);
+    //     let dataStr: string = message.split("data: ")[1]
+    //     if (dataStr && dataStr.startsWith("{")) {
+    //       try {
+    //         let json = JSON.parse(dataStr);
+    //         let content = json.choices[0].delta.content
+    //         this.gptre = this.gptre + content
+    //       } catch (err) { }
+    //     }
+
+
+    //   }
+    // }
+
+
+  }
+
+  userPrompt: string = ""
+  promptInput(ev: any) {
+    this.userPrompt = ev.detail.value;
+  }
+  imagineWork: ImagineWork | undefined
+  images: Array<string> = []
+  constructor(
+  ) {
+    // 示例任务,自己生成图片后请存储新的ID
+    console.log('ImagineWork instance:', this.imagineWork);
+    this.imagineWork = new ImagineWork("EXOVSbrmMK");
+    this.imagineWork.fetchTask().then(work => {
+      this.images = this.imagineWork?.images || [];
+    })
+  }
+  picdetail: string = ""
+  async createImage() {
+    let promotTemplate = `您是一名专业的美术画家,请您根据服装描述内容,将其描述的服装细节描述出来,服装描述如下:${this.gptre}`
+    let completion = new FmodeChatCompletion([
+      { role: "system", content: "" },
+      { role: "user", content: promotTemplate }
+    ])
+
+    completion.sendCompletion().subscribe((message: any) => {
+      // 打印消息体
+      console.log(message.content)
+      // 赋值消息内容给组件内属性
+      this.picdetail = message.content
+      if (message?.complete) {
+        this.imagineWork = new ImagineWork();
+        let options: DalleOptions = { prompt: this.picdetail }
+        this.imagineWork.draw(options).subscribe(work => {
+          console.log("imagineWork", work?.toJSON())
+          console.log("images", work?.get("images"))
+          if (work?.get("images")?.length) {
+            this.images = work?.get("images");
+          }
+        })
+      }
+    })
+
+
+
+  }
 }

+ 99 - 0
tailor-app/myapp/src/app/customization/test-chat-completion.ts

@@ -0,0 +1,99 @@
+export interface TestChatMessage{
+    role:string
+    content:string
+}
+export class TestChatCompletion{
+messageList:Array<TestChatMessage>
+constructor(messageList:Array<TestChatMessage>){
+    this.messageList = messageList
+}
+async createCompletionByStream() {
+
+let token = localStorage.getItem("token");
+let bodyJson = {
+  "token": `Bearer ${token}`,
+  "messages": this.messageList,
+  "model": "fmode-4.5-128k",
+  "temperature": 0.5,
+  "presence_penalty": 0,
+  "frequency_penalty": 0,
+  "top_p": 1,
+  "stream":true
+};
+
+let response = await fetch("https://test.fmode.cn/api/apig/aigc/gpt/v1/chat/completions", {
+  "headers": {
+    "accept": "text/event-stream",
+    "sec-fetch-dest": "empty",
+    "sec-fetch-mode": "cors",
+    "sec-fetch-site": "same-site"
+  },
+  "referrer": "https://ai.fmode.cn/",
+  "referrerPolicy": "strict-origin-when-cross-origin",
+  "body": JSON.stringify(bodyJson),
+  "method": "POST",
+  "mode": "cors",
+  "credentials": "omit"
+});
+
+let messageAiReply = ""
+let messageIndex = this.messageList.length
+let reader = response.body?.getReader();
+if (!reader) {
+  throw new Error("Failed to get the response reader.");
+}
+
+let decoder = new TextDecoder();
+let buffer = "";
+
+while (true) {
+  let { done, value } = await reader.read();
+  if (done) {
+    break;
+  }
+
+  buffer += decoder.decode(value);
+
+  // Split the buffer by newlines to get individual messages
+  let messages = buffer.split("\n");
+
+  // Process each message
+  for (let i = 0; i < messages.length - 1; i++) {
+    let message = messages[i];
+
+    // Process the message as needed
+    /**
+     * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"fmode-4.5-128k","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
+     * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"fmode-4.5-128k","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
+     * data: [DONE]
+     */
+    let dataText = message.replace("data:\ ","")
+    if(dataText.startsWith("{")){
+      try{
+        let dataJson = JSON.parse(dataText)
+        console.log(dataJson)
+        messageAiReply += dataJson?.choices?.[0]?.delta?.content || ""
+        this.messageList[messageIndex] = {
+          role:"assistant",
+          content:messageAiReply
+        }
+      }catch(err){}
+    }
+    if(dataText.startsWith("[")){
+      console.log(message)
+      console.log("完成")
+      this.messageList[messageIndex] = {
+        role:"assistant",
+        content:messageAiReply
+      }
+      messageAiReply = ""
+    }
+    // Parse the message as JSON
+    // let data = JSON.parse(message);
+
+    // Clear the processed message from the buffer
+    buffer = buffer.slice(message.length + 1);
+  }
+}
+}
+}

+ 11 - 0
tailor-app/myapp/src/app/edit-tag/edit-tag.component.html

@@ -0,0 +1,11 @@
+
+
+  
+  
+    <ion-input [value]="userInputText" (ionInput)="onInput($event)" type="" ></ion-input>
+    <!-- <p>当前输入{{userInputText}}</p> -->
+    <ion-button (click)="addtag()">添加标签</ion-button>
+    @for(tag of tags;track tag;){
+      <ion-chip>{{tag}} <span (click)="deleteTag(tag)">x</span></ion-chip>
+    }
+    

+ 0 - 0
tailor-app/myapp/src/app/edit-tag/edit-tag.component.scss


+ 24 - 0
tailor-app/myapp/src/app/edit-tag/edit-tag.component.spec.ts

@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { EditTagComponent } from './edit-tag.component';
+
+describe('EditTagComponent', () => {
+  let component: EditTagComponent;
+  let fixture: ComponentFixture<EditTagComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [ EditTagComponent ],
+      imports: [IonicModule.forRoot()]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(EditTagComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 43 - 0
tailor-app/myapp/src/app/edit-tag/edit-tag.component.ts

@@ -0,0 +1,43 @@
+import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { IonContent, IonHeader, IonTitle, IonToolbar, IonButton, IonInput, IonChip, IonItem, IonList } from '@ionic/angular/standalone';
+
+@Component({
+  selector: 'app-edit-tag',
+  templateUrl: './edit-tag.component.html',
+  styleUrls: ['./edit-tag.component.scss'],
+  standalone: true,
+  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule,IonButton,IonInput,IonChip,IonItem,IonList]
+
+})
+export class EditTagComponent  implements OnInit {
+  public inputValue = ""
+  public gptre = ""
+  tags:Array<string>=[]
+
+  userInputText:string=""
+  onInput(event:any){
+  this.userInputText=  event.detail.value
+    
+  }
+  deleteTag(tag:string){
+    let idx=this.tags.findIndex(item=>item==tag)
+    this.tags.splice(idx,1)
+
+  }
+  addtag(){
+    this.tags.push(this.userInputText);
+    this.userInputText=""
+    this.onTagChange.emit(this.tags)
+  }
+  @Output()
+  onTagChange:EventEmitter<Array<string>>=new EventEmitter<Array<string>>()
+  constructor() { }
+
+  ngOnInit() {
+  }
+  
+
+  
+}

BIN
tailor-app/myapp/src/app/me/img/绘图1.jpg


+ 233 - 7
tailor-app/myapp/src/app/me/me.page.html

@@ -1,13 +1,239 @@
 <ion-header [translucent]="true">
-  <ion-toolbar>
+  <ion-toolbar color="success">
     <ion-title>me</ion-title>
   </ion-toolbar>
 </ion-header>
 
 <ion-content [fullscreen]="true">
-  <ion-header collapse="condense">
-    <ion-toolbar>
-      <ion-title size="large">me</ion-title>
-    </ion-toolbar>
-  </ion-header>
-</ion-content>
+
+    <!-- GPT组件 -->
+    <h1>GPT组件</h1>
+     <ion-input type="" [(ngModel)]="inputValue"  ></ion-input>
+    <ion-button (click)="printInputValue()">提交</ion-button>
+   {{gptre}}
+
+
+  <h1>页面跳转和组件使用</h1>
+  <!-- 页面跳转和组件使用 -->
+  <ion-button [routerLink]="[ '/yiyun' ]">
+    跳转到yiyun
+  </ion-button>
+
+  <app-slide></app-slide>
+  <h1>button组件调用</h1>
+  <!-- button组件调用 -->
+  <ion-button [routerLink]="[ '/yiyun' ]" color="warning">
+    修改按钮颜色
+  </ion-button>
+ 
+  <ion-buttons slot="start">
+    <ion-back-button>返回i按钮</ion-back-button>
+  </ion-buttons>
+
+  <ion-button expand="block">
+    按钮可以block
+  </ion-button>
+
+  <ion-button expand="full">
+    按钮可以直角
+  </ion-button>
+
+  <ion-button fill="clear" expand="block">
+    按钮可以透明背景填充
+  </ion-button>
+
+  <ion-button>
+    <ion-icon slot="icon-only" name="add"></ion-icon>
+  </ion-button>
+  <ion-button fill="clear">
+    <ion-icon slot="icon-only" name="add"></ion-icon>
+  </ion-button>
+
+  <ion-button size="small">
+    小按钮
+  </ion-button>
+  <ion-button size="large">
+    大按钮
+  </ion-button>
+
+  <ion-button mode="ios" color="primary">
+    ios按钮
+  </ion-button>
+  <ion-button mode="md" color="primary">
+    android按钮
+  </ion-button>
+
+  <ion-button>
+    <ion-icon name="add" slot="start"></ion-icon>
+    图片在左侧文字在右侧按钮
+  </ion-button>
+  <ion-button>
+    <ion-icon name="add" slot="end"></ion-icon>
+    图片在右侧文字在右侧按钮
+  </ion-button>
+
+  <!-- List组件调用 -->
+  <h1>List组件调用 </h1>
+  <ion-list lines="full">
+    <ion-item *ngFor="let item of list" [routerLink]="[ '/yiyun' ]">
+      {{item}}
+    </ion-item>
+  </ion-list>
+
+  <ion-list>
+    <ion-item-divider>
+      <ion-label>分组列表A</ion-label>
+    </ion-item-divider>
+    <ion-item>
+      a
+    </ion-item>
+    <ion-item>
+      aaa
+    </ion-item>
+
+    <ion-item-divider>
+      <ion-label>B</ion-label>
+    </ion-item-divider>
+    <ion-item>
+      b
+    </ion-item>
+    <ion-item>
+      bbb
+    </ion-item>
+  </ion-list>
+
+  <ion-list lines="full">
+    <ion-item *ngFor="let item of list">
+      <ion-icon slot="start" name="add"></ion-icon>
+      带图标列表{{item}}
+    </ion-item>
+  </ion-list>
+
+  <ion-list>
+    <ion-item *ngFor="let item of list">
+      <ion-avatar item-left>
+        <img src="assets/shapes.svg">
+      </ion-avatar>
+      <ion-label>列表中的头像</ion-label>
+    </ion-item>
+  </ion-list>
+
+  <ion-list>
+    <ion-item *ngFor="let item of list">
+      <ion-thumbnail item-left>
+        <img src="assets/shapes.svg">
+      </ion-thumbnail>
+      <div>
+        <h2>我是标题</h2>
+        <p>我是新闻</p>
+      </div>
+      <button ion-button clear item-right></button>
+    </ion-item>
+  </ion-list>
+
+  <ion-list>
+    <ion-item-sliding>
+      <ion-item>
+        <ion-label>滑动列表1</ion-label>
+      </ion-item>
+      <ion-item-options side="start">
+        <ion-item-option>Favorite</ion-item-option>
+        <ion-item-option color="primary">Share</ion-item-option>
+      </ion-item-options>
+
+      <ion-item-options side="end">
+        <ion-item-option>Unread</ion-item-option>
+      </ion-item-options>
+    </ion-item-sliding>
+
+    <ion-item-sliding>
+      <ion-item>
+        <ion-label>滑动列表2</ion-label>
+      </ion-item>
+      <ion-item-options side="start">
+        <ion-item-option>Favorite</ion-item-option>
+        <ion-item-option color="primary">Share</ion-item-option>
+      </ion-item-options>
+
+      <ion-item-options side="end">
+        <ion-item-option>Unread</ion-item-option>
+      </ion-item-options>
+    </ion-item-sliding>
+  </ion-list>
+  <!-- 表单组件 -->
+  <h1>表单组件</h1>
+
+  <ion-list>
+    <ion-item>
+      <ion-label>用户名</ion-label>
+      <ion-input [(ngModel)]="peopleInfo.username"></ion-input>
+    </ion-item>
+
+    <ion-item>
+      <ion-label>是否本科</ion-label>
+      <ion-toggle slot="end" [(ngModel)]="peopleInfo.flag"></ion-toggle>
+    </ion-item>
+
+    <ion-radio-group [(ngModel)]="peopleInfo.payType">
+      <ion-item>
+        <ion-avatar item-left>
+          <img src="assets/shapes.svg">
+        </ion-avatar>
+        <ion-label>支付宝支付</ion-label>
+        <ion-radio value="1"></ion-radio>
+      </ion-item>
+
+      <ion-item>
+        <ion-avatar item-left>
+          <img src="assets/shapes.svg">
+        </ion-avatar>
+        <ion-label>微信支付</ion-label>
+        <ion-radio value="2"></ion-radio>
+      </ion-item>
+
+    </ion-radio-group>
+
+    <ion-item>
+      <ion-label>checkbox</ion-label>
+      <ion-checkbox></ion-checkbox>
+    </ion-item>
+  </ion-list>
+  {{peopleInfo|json}}
+
+  <!-- 搜索框 -->
+  <h1>搜索框</h1>
+  <ion-searchbar animated="true" placeholder="Animated"></ion-searchbar>
+  <ion-searchbar placeholder="Filter Pizza" (ionInput)="onSearchInput($event)" animated></ion-searchbar>
+
+  <!-- segment演示 -->
+  <h1>segment演示</h1>
+  <ion-segment [(ngModel)]="tab">
+    <ion-segment-button value="tab1">
+      <ion-label>详情</ion-label>
+    </ion-segment-button>
+    <ion-segment-button value="tab2">
+      <ion-label>评论</ion-label>
+    </ion-segment-button>
+
+    <div class="info" [ngSwitch]="tab">
+      <div *ngSwitchCase="'tab1'">商品简介</div>
+      <div *ngSwitchCase="'tab2'">商品评论</div>
+
+    </div>
+
+
+    {{tab}}
+
+    <!-- 日期组件 -->
+    <h1>日期组件</h1>
+    <ion-list>
+
+      <ion-item>
+        <ion-label>Date</ion-label>
+        <ion-datetime display-format="DD.MM.YYYY HH:mm"></ion-datetime>
+      </ion-item>
+    </ion-list>
+  </ion-segment>
+
+
+</ion-content>

+ 109 - 5
tailor-app/myapp/src/app/me/me.page.ts

@@ -1,20 +1,124 @@
 import { Component, OnInit } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
-import { IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { IonContent, IonHeader, IonTitle, IonToolbar, IonButton, IonLabel, IonItem, IonList, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemOption, IonItemSliding, IonInput, IonCheckbox, IonRadio, IonToggle, IonRadioGroup, IonSearchbar, IonSegment, IonSegmentButton, IonDatetime } from '@ionic/angular/standalone';
+import { RouterModule } from '@angular/router';
+import { SlideModule } from '../module/slide/slide.module';
+import { addIcons } from 'ionicons';
+import { add } from 'ionicons/icons';
+// import {FmodeChatCompletion} from "fmode-ng"
+import { TestChatCompletion } from './test-chat-completion';
 
+addIcons({ add })
 @Component({
   selector: 'app-me',
   templateUrl: './me.page.html',
   styleUrls: ['./me.page.scss'],
   standalone: true,
-  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule]
+  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule, IonButton, RouterModule, IonLabel, IonLabel, IonList, IonItem, SlideModule, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemSliding, IonItemOption, IonItemOptions, IonInput, IonCheckbox, IonRadio, IonToggle, IonRadioGroup, IonSearchbar, IonSegment, IonSegmentButton, IonDatetime]
 })
 export class MePage implements OnInit {
-
+  public list: any = []
+  public tab = "tab1"
   constructor() { }
-
+  public inputValue = ""
+  public gptre = ""
+  public peopleInfo: any = {
+    username: '',
+    age: 20,
+    flag: true,
+    payType: '1',
+    checkBoxList: [
+      { val: '吃饭', ischecked: true },
+      { val: '睡觉', ischecked: false },
+      { val: '敲代码', ischecked: false }
+    ],
+    cityList: ['北京', '上海', '深圳'],
+    city: '北京'
+  }
   ngOnInit() {
+    for (var i = 0; i < 5; i++) {
+      this.list.push(`aaaaaaa${i}`);
+    }
+  }
+  onSearchInput(event: any) {
+    console.log(event.target.value);
   }
+  async printInputValue() {
+    console.log("开始解析");
+
+    let token = "r:16cd8f27084ff647fcdb5308a6783c4c"
+    localStorage.setItem("token",token)
+    let messageList: any = [
+      {
+        role: "system", content: `${new Date().toLocaleString}`
+      },
+      {
+        role: "user", content: this.inputValue
+      }
+    ]
+
+    let completion=new TestChatCompletion(messageList)
+    completion.createCompletionByStream()
+    setInterval(()=>{
+      console.log(messageList);
+      this.gptre=messageList[messageList.length-1].content
+    },1000)
+
+
+    // let bodyJson = {
+    //   "token": `Bearer ${token}`,
+    //   "messages": messageList,
+    //   "model": "fmode-4.5-128k",
+    //   "temperature": 0.5,
+    //   "presence_penalty": 0,
+    //   "frequency_penalty": 0,
+    //   "top_p": 1,
+    //   "stream": true
+    // };
 
-}
+    // let response = await fetch("https://test.fmode.cn/api/apig/aigc/gpt/v1/chat/completions", {
+    //   "headers": {
+    //     "accept": "text/event-stream",
+    //   },
+    //   "body": JSON.stringify(bodyJson),
+    //   "method": "POST",
+    //   "mode": "cors",
+    //   "credentials": "omit"
+    // });
+    // let reader = response.body?.getReader()
+    // if (!reader) {
+    //   throw new Error("Failed to get the response reader.");
+    // }
+
+    // let decoder = new TextDecoder();
+    // let buffer = "";
+
+    // while (true) {
+    //   let { done, value } = await reader.read();
+    //   if (done) {
+    //     break;
+    //   }
+    //   let data = decoder.decode(value);
+    //   let messages = data.split("\n");
+    //   console.log(messages);
+
+    //   for (let i = 0; i < messages.length - 1; i++) {
+    //     let message = messages[i];
+    //     console.log(message);
+    //     let dataStr: string = message.split("data: ")[1]
+    //     if (dataStr && dataStr.startsWith("{")) {
+    //       try {
+    //         let json = JSON.parse(dataStr);
+    //         let content = json.choices[0].delta.content
+    //         this.gptre = this.gptre + content
+    //       } catch (err) { }
+    //     }
+
+
+    //   }
+    // }
+
+
+  }
+}

+ 99 - 0
tailor-app/myapp/src/app/me/test-chat-completion.ts

@@ -0,0 +1,99 @@
+export interface TestChatMessage{
+    role:string
+    content:string
+}
+export class TestChatCompletion{
+messageList:Array<TestChatMessage>
+constructor(messageList:Array<TestChatMessage>){
+    this.messageList = messageList
+}
+async createCompletionByStream() {
+
+let token = localStorage.getItem("token");
+let bodyJson = {
+  "token": `Bearer ${token}`,
+  "messages": this.messageList,
+  "model": "fmode-4.5-128k",
+  "temperature": 0.5,
+  "presence_penalty": 0,
+  "frequency_penalty": 0,
+  "top_p": 1,
+  "stream":true
+};
+
+let response = await fetch("https://test.fmode.cn/api/apig/aigc/gpt/v1/chat/completions", {
+  "headers": {
+    "accept": "text/event-stream",
+    "sec-fetch-dest": "empty",
+    "sec-fetch-mode": "cors",
+    "sec-fetch-site": "same-site"
+  },
+  "referrer": "https://ai.fmode.cn/",
+  "referrerPolicy": "strict-origin-when-cross-origin",
+  "body": JSON.stringify(bodyJson),
+  "method": "POST",
+  "mode": "cors",
+  "credentials": "omit"
+});
+
+let messageAiReply = ""
+let messageIndex = this.messageList.length
+let reader = response.body?.getReader();
+if (!reader) {
+  throw new Error("Failed to get the response reader.");
+}
+
+let decoder = new TextDecoder();
+let buffer = "";
+
+while (true) {
+  let { done, value } = await reader.read();
+  if (done) {
+    break;
+  }
+
+  buffer += decoder.decode(value);
+
+  // Split the buffer by newlines to get individual messages
+  let messages = buffer.split("\n");
+
+  // Process each message
+  for (let i = 0; i < messages.length - 1; i++) {
+    let message = messages[i];
+
+    // Process the message as needed
+    /**
+     * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"fmode-4.5-128k","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
+     * data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"fmode-4.5-128k","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
+     * data: [DONE]
+     */
+    let dataText = message.replace("data:\ ","")
+    if(dataText.startsWith("{")){
+      try{
+        let dataJson = JSON.parse(dataText)
+        console.log(dataJson)
+        messageAiReply += dataJson?.choices?.[0]?.delta?.content || ""
+        this.messageList[messageIndex] = {
+          role:"assistant",
+          content:messageAiReply
+        }
+      }catch(err){}
+    }
+    if(dataText.startsWith("[")){
+      console.log(message)
+      console.log("完成")
+      this.messageList[messageIndex] = {
+        role:"assistant",
+        content:messageAiReply
+      }
+      messageAiReply = ""
+    }
+    // Parse the message as JSON
+    // let data = JSON.parse(message);
+
+    // Clear the processed message from the buffer
+    buffer = buffer.slice(message.length + 1);
+  }
+}
+}
+}

+ 3 - 0
tailor-app/myapp/src/app/module/slide/slide.component.html

@@ -0,0 +1,3 @@
+<p>
+  slide works!
+</p>

+ 0 - 0
tailor-app/myapp/src/app/module/slide/slide.component.scss


+ 24 - 0
tailor-app/myapp/src/app/module/slide/slide.component.spec.ts

@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { SlideComponent } from './slide.component';
+
+describe('SlideComponent', () => {
+  let component: SlideComponent;
+  let fixture: ComponentFixture<SlideComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [ SlideComponent ],
+      imports: [IonicModule.forRoot()]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(SlideComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 14 - 0
tailor-app/myapp/src/app/module/slide/slide.component.ts

@@ -0,0 +1,14 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-slide',
+  templateUrl: './slide.component.html',
+  styleUrls: ['./slide.component.scss'],
+})
+export class SlideComponent  implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {}
+
+}

+ 13 - 0
tailor-app/myapp/src/app/module/slide/slide.module.ts

@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { SlideComponent } from './slide.component';
+
+
+@NgModule({
+  declarations: [SlideComponent],
+  imports: [
+    CommonModule,
+  ],
+  exports:[SlideComponent]
+})
+export class SlideModule { }

+ 32 - 12
tailor-app/myapp/src/app/store/store.page.html

@@ -1,13 +1,33 @@
-<ion-header [translucent]="true">
-  <ion-toolbar>
-    <ion-title>store</ion-title>
-  </ion-toolbar>
-</ion-header>
 
-<ion-content [fullscreen]="true">
-  <ion-header collapse="condense">
-    <ion-toolbar>
-      <ion-title size="large">store</ion-title>
-    </ion-toolbar>
-  </ion-header>
-</ion-content>
+<ion-content>
+  <ion-card style="width: 90%;margin: auto;margin-top: 10px;margin-bottom: 10px;">
+    <ion-card-header>
+      <ion-card-title>各类服装年销售量渐变堆叠面积图</ion-card-title>
+    </ion-card-header>
+    <ion-card-content>
+      <p>5年内服装销售量</p>
+      <p>随时间或其他变量的变化趋势和相对大小</p>
+     
+
+<ion-button style="border-color: yellow;" expand="block" (click)="shengcheng1()"><ion-icon name="podium-outline" style="margin-right: 5px;"></ion-icon> VIP一键生成</ion-button>
+    </ion-card-content>
+  </ion-card>
+  @if(Progressvisable1){
+    <ion-progress-bar [buffer]="buffer" [value]="progress"></ion-progress-bar>
+  }
+  @if( Chartvisable1){
+    <ion-list style="width: 100%;margin: auto;margin-top: 20px;">
+      <ion-item>
+        <h1 style="font-weight: bolder;">2017-2023 各类服装年销售量渐变堆叠面积图</h1>
+      </ion-item>
+      <ion-item class="noPadding">
+        <div class="echarts " id="chart" ></div>
+        
+          
+      </ion-item>
+      <ion-button (click)="this.Chartvisable1=false">隐藏</ion-button>
+    </ion-list>
+  }
+  
+  
+</ion-content>

+ 38 - 0
tailor-app/myapp/src/app/store/store.page.scss

@@ -0,0 +1,38 @@
+.echarts{
+    width: 380px;
+    height: 200px;
+    margin: 0 auto;
+}
+.item-native{
+    margin: 0;
+    padding: 0;
+}
+.noPadding{
+    --padding-start:0
+    --inner-padding-end:0
+}
+ion-button {
+    --background: #000;
+    --background-hover: #9ce0be;
+    --background-activated: #88f4be;
+    --background-focused: #88f4be;
+  
+    --color: #ecc422;
+  
+    --border-radius: 0;
+    --border-color: #000;
+    --border-style: solid;
+    --border-width: 1px;
+  
+    --box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);
+  
+    --ripple-color: deeppink;
+  
+    --padding-top: 10px;
+    --padding-bottom: 10px;
+  }
+
+  ion-progress-bar {
+    --background: #f3e895;
+    --progress-background: #f7ef18;;
+  }

+ 229 - 3
tailor-app/myapp/src/app/store/store.page.ts

@@ -1,20 +1,246 @@
 import { Component, OnInit } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
-import { IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
-
+import { IonContent, IonHeader, IonTitle, IonToolbar, IonButton, IonLabel, IonItem, IonList, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemOption, IonItemSliding, IonInput, IonCheckbox, IonRadio, IonToggle, IonRadioGroup, IonSearchbar,IonSegment,IonSegmentButton,IonDatetime,IonFooter,IonCardContent,IonCardTitle,IonCardHeader,IonCard,IonCol,IonRow,IonGrid,IonChip,IonImg,IonProgressBar } from '@ionic/angular/standalone';
+import * as echarts from 'echarts';
+import { podiumOutline} from 'ionicons/icons';
+import { addIcons } from 'ionicons';
+addIcons({podiumOutline})
+// <ion-icon name="podium-outline"></ion-icon>
+// <ion-icon name="bar-chart-outline"></ion-icon>
+// <ion-icon name="cellular-outline"></ion-icon>
 @Component({
   selector: 'app-store',
   templateUrl: './store.page.html',
   styleUrls: ['./store.page.scss'],
   standalone: true,
-  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule]
+  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule, IonButton,  IonLabel, IonLabel, IonList, IonItem, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemSliding, IonItemOption, IonItemOptions,IonInput,IonCheckbox,IonRadio,IonToggle,IonRadioGroup,IonSearchbar,IonSegment,IonSegmentButton,IonDatetime,IonFooter,IonCardContent,IonCardTitle,IonCardHeader,IonCard,IonCol,IonRow,IonGrid,IonChip,IonImg,IonProgressBar ]
 })
 export class StorePage implements OnInit {
 
   constructor() { }
 
   ngOnInit() {
+    
+    
   }
+  //进度条
+  public buffer = 0.06;
+  public progress = 0;
+  public Progressvisable1:boolean=false
+  public Chartvisable1:boolean=false
+
+ shengcheng1(){
+  this.Progressvisable1=true
+    let inter1=setInterval(() => {
+      this.buffer += 0.4;
+      this.progress += 0.4;
 
+      // Reset the progress bar when it reaches 100%
+      // to continuously show the demo
+      if (this.progress > 1) {
+        setTimeout(() => {
+          clearInterval(inter1)
+          this.buffer = 0.06;
+          this.progress = 0;
+          this.Progressvisable1=false
+          this.Chartvisable1=true
+          this.initEchart();
+        }, 1000);
+      }
+    }, 1000);
+    
+  }
+  public chart: any;
+  initEchart() {
+    let ec = echarts as any;
+    let container = document.getElementById('chart');
+    this.chart = ec.init(container);
+    let option = {
+      color: ['#80FFA5', '#00DDFF', '#37A2FF', '#FF0087', '#FFBF00'],
+      title: {
+        text: ''
+      },
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+          type: 'cross',
+          label: {
+            backgroundColor: '#6a7985'
+          }
+        }
+      },
+      legend: {
+        data: ['风衣', '羽绒服', 'T恤', '牛仔裤', '连衣裙']
+      },
+      toolbox: {
+        feature: {
+          saveAsImage: {}
+        }
+      },
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
+      },
+      xAxis: [
+        {
+          type: 'category',
+          boundaryGap: false,
+           data: ['2017', '2018', '2019', '2020', '2021', '2022', '2023']
+        }
+      ],
+      yAxis: [
+        {
+          type: 'value'
+        }
+      ],
+      series: [
+        {
+          name: '风衣',
+          type: 'line',
+          stack: 'Total',
+          smooth: true,
+          lineStyle: {
+            width: 0
+          },
+          showSymbol: false,
+          areaStyle: {
+            opacity: 0.8,
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: 'rgb(128, 255, 165)'
+              },
+              {
+                offset: 1,
+                color: 'rgb(1, 191, 236)'
+              }
+            ])
+          },
+          emphasis: {
+            focus: 'series'
+          },
+          data: [140, 232, 101, 264, 90, 340, 250]
+        },
+        {
+          name: '羽绒服',
+          type: 'line',
+          stack: 'Total',
+          smooth: true,
+          lineStyle: {
+            width: 0
+          },
+          showSymbol: false,
+          areaStyle: {
+            opacity: 0.8,
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: 'rgb(0, 221, 255)'
+              },
+              {
+                offset: 1,
+                color: 'rgb(77, 119, 255)'
+              }
+            ])
+          },
+          emphasis: {
+            focus: 'series'
+          },
+          data: [120, 282, 111, 234, 220, 340, 310]
+        },
+        {
+          name: 'T恤',
+          type: 'line',
+          stack: 'Total',
+          smooth: true,
+          lineStyle: {
+            width: 0
+          },
+          showSymbol: false,
+          areaStyle: {
+            opacity: 0.8,
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: 'rgb(55, 162, 255)'
+              },
+              {
+                offset: 1,
+                color: 'rgb(116, 21, 219)'
+              }
+            ])
+          },
+          emphasis: {
+            focus: 'series'
+          },
+          data: [320, 132, 201, 334, 190, 130, 220]
+        },
+        {
+          name: '牛仔裤',
+          type: 'line',
+          stack: 'Total',
+          smooth: true,
+          lineStyle: {
+            width: 0
+          },
+          showSymbol: false,
+          areaStyle: {
+            opacity: 0.8,
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: 'rgb(255, 0, 135)'
+              },
+              {
+                offset: 1,
+                color: 'rgb(135, 0, 157)'
+              }
+            ])
+          },
+          emphasis: {
+            focus: 'series'
+          },
+          data: [220, 402, 231, 134, 190, 230, 120]
+        },
+        {
+          name: '连衣裙',
+          type: 'line',
+          stack: 'Total',
+          smooth: true,
+          lineStyle: {
+            width: 0
+          },
+          showSymbol: false,
+          label: {
+            show: true,
+            position: 'top'
+          },
+          areaStyle: {
+            opacity: 0.8,
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: 'rgb(255, 191, 0)'
+              },
+              {
+                offset: 1,
+                color: 'rgb(224, 62, 76)'
+              }
+            ])
+          },
+          emphasis: {
+            focus: 'series'
+          },
+          data: [220, 302, 181, 234, 210, 290, 150]
+        }
+      ]
+    };
+    
+    
+ 
+    this.chart.setOption(option);
+}
 }

+ 1 - 1
tailor-app/myapp/src/app/tabs/tabs.page.html

@@ -1,4 +1,4 @@
-<ion-tabs>
+<ion-tabs style="background-color: aqua;">
   <ion-tab-bar slot="bottom">
     <ion-tab-button tab="customization" href="/tabs/customization">
       <ion-icon name="color-palette-outline"></ion-icon>

+ 3 - 0
tailor-app/myapp/src/app/tabs/tabs.page.scss

@@ -1 +1,4 @@
 
+.tabbar {
+    background-color: #5c2626 !important; // 使用!important可以确保样式被优先应用
+  }

+ 167 - 9
tailor-app/myapp/src/app/yiyun/yiyun.page.html

@@ -1,16 +1,174 @@
-<ion-header>
-  <ion-toolbar>
-    <ion-title>
-      搜索栏示例
-    </ion-title>
-    <ion-searchbar (ionInput)="onSearchInput($event)" placeholder="搜索..."></ion-searchbar>
+<!-- 页面顶部导航栏 -->
+<ion-header class="ion-no-border" style="background-color: rgb(231, 244, 247);;">
+  <ion-toolbar style="background-color: rgb(231, 244, 247);;">
+    <ion-searchbar animated="true" placeholder="Animated"></ion-searchbar>
+    <ion-buttons slot="end">
+      <!-- <ion-button size="small">登录/注册</ion-button> -->
+      <!-- <ion-button size="small">商家后台入口</ion-button> -->
+    </ion-buttons>
   </ion-toolbar>
 </ion-header>
 
+<!-- 品牌展示区 -->
 <ion-content>
-  <ion-list>
-    <ion-item *ngFor="let item of filteredItems">
-      {{ item }}
+  <!-- <ion-slides>
+      <ion-slide>
+        <img src="最新服装定制案例图片路径" alt="服装定制案例">
+      </ion-slide>
+      <ion-slide>
+        <img src="时尚活动照片路径" alt="时尚活动">
+      </ion-slide>
+    </ion-slides> -->
+  <ion-grid>
+    <ion-row>
+      <ion-col *ngFor="let item of items; let i = index" class="custom-padding">
+        <div class="button-container">
+          <ion-icon size="large" [name]="item.image"></ion-icon>
+          <p class="item-text" style="font-weight: bolder;">{{ item.text }}</p>
+        </div>
+      </ion-col>
+    </ion-row>
+  </ion-grid>
+
+  <ion-grid style="justify-content: center;display: flex;">
+    <ion-row style="background-color: white;width: 90%;border-radius: 10px;">
+      <ion-card style="width: 44%;box-shadow: none;">
+        <ion-card-header>
+          <img src="assets/img/ding.png" alt="">
+          <ion-card-title style="font-size: 17px;font-weight:bolder;">定制服务</ion-card-title>
+        </ion-card-header>
+        <!-- <ion-card-content>
+            <ion-button expand="block">点击参与最新定制活动</ion-button>
+          </ion-card-content> -->
+      </ion-card>
+
+      <!-- 用户定制入口 -->
+      <ion-card style="width: 44%;box-shadow: none;">
+        <ion-card-header>
+          <img src="assets/img/3d.png" alt="">
+          <ion-card-title style="font-size: 17px;font-weight:bolder;">3D试衣服务</ion-card-title>
+        </ion-card-header>
+
+      </ion-card>
+    </ion-row>
+  </ion-grid>
+
+
+
+  <!-- 特色服务展示 -->
+  <!-- <ion-grid>
+      <ion-row>
+        <ion-col size="6">
+          <ion-card>
+            <ion-icon name="camera"></ion-icon> 假设AI定制对应的ion-icon名称为ai-outline,需替换准确图标名
+            <ion-card-header>
+              <ion-card-title>AI智能推荐,精准匹配</ion-card-title>
+            </ion-card-header>
+          </ion-card>
+        </ion-col>
+        <ion-col size="6">
+          <ion-card>
+            <ion-icon name="camera"></ion-icon> 假设虚拟试衣对应的ion-icon名称为body-outline,需替换准确图标名
+            <ion-card-header>
+              <ion-card-title>虚拟试衣体验,先试后买</ion-card-title>
+            </ion-card-header>
+          </ion-card>
+        </ion-col>
+      </ion-row>
+    </ion-grid> -->
+
+  <!-- 用户评价和案例展示 -->
+
+  <ion-list style="width: 90%;margin: auto;margin-top: 20px;">
+    <ion-item>
+      <h1 style="font-weight: bolder;">用户评价和案例展示</h1>
+    </ion-item>
+    <ion-item>
+
+      <ion-label>
+        <ion-grid>
+          <ion-row>
+            <ion-col size="auto">
+
+            </ion-col>
+            <ion-col width-10>
+              <ion-avatar
+                style="width: 30px;height: 30px;display: inline-block;vertical-align: middle;margin-right: 10px;">
+                <img src="assets/shapes.svg" alt="用户头像">
+              </ion-avatar>
+              <h2 style="font-weight: bolder;display: inline-block;">小林</h2>
+              <div style="margin-top: 10px;margin-bottom: 10px;">
+                衣服非常合身,面料舒适,非常满意!这件服装简直是时尚与艺术的完美融合,让人一眼难忘!从设计到剪裁,每一个细节都透露着匠人的精湛技艺与独到眼光。面料质感丝滑,穿着舒适亲肤,色彩搭配既经典又不失前卫感,完美衬托出穿着者的独特气质。
+              </div>
+            </ion-col>
+          </ion-row>
+          <ion-row>
+            <img src="assets/img/shi.png" alt="定制案例">
+
+          </ion-row>
+        </ion-grid>
+      </ion-label>
     </ion-item>
   </ion-list>
+
+  <!-- 商家管理入口 -->
+  <ion-card style="width: 90%;margin: auto;margin-bottom: 10px;margin-top: 10px;">
+    <ion-card-content>
+
+      <ion-button expand="block"><ion-icon name="camera"></ion-icon> 一键入库</ion-button>
+      <p>智能库存管理,让生意更简单</p>
+    </ion-card-content>
+  </ion-card>
+
+  <ion-list style="width: 90%;margin: auto;margin-top: 20px;">
+    <ion-item>
+      <h1 style="font-weight: bolder;">AI智能推荐</h1>
+    </ion-item>
+    <ion-item>
+
+
+        <ion-grid fixed style="width: 100%;">
+          <ion-row>
+            <ion-col size="6" *ngFor="let product of products" [attr.data-order]="product.order">
+              <ion-card>
+                <ion-img [src]="product.image"></ion-img>
+                <ion-card-header>
+                  <ion-card-title>{{ product.name }}</ion-card-title>
+                </ion-card-header>
+                <ion-card-content>
+                  <p>{{ product.description }}</p>
+                  <ion-button fill="clear">{{ product.price | currency }}</ion-button>
+                </ion-card-content>
+              </ion-card>
+            </ion-col>
+          </ion-row>
+        </ion-grid>
+    </ion-item>
+  </ion-list>
+
+
+
+  <!-- 最新时尚资讯 -->
+  <ion-card style="width: 90%;margin: auto;margin-top: 10px;margin-bottom: 10px;">
+    <ion-card-header>
+      <ion-card-title>2024年春季流行趋势</ion-card-title>
+    </ion-card-header>
+    <ion-card-content>
+      <p>本季流行色、面料及搭配建议一览</p>
+      <ion-button expand="block">了解更多</ion-button>
+    </ion-card-content>
+  </ion-card>
+
+  <!-- 页面底部 -->
+  <!-- <ion-footer>
+      <ion-toolbar>
+        <ion-label>© 2024 个性化定制服装平台</ion-label>
+        <ion-buttons slot="end">
+          <ion-button>客服热线:400-xxx-xxxx</ion-button>
+          <ion-button>关于我们</ion-button>
+          <ion-button>合作伙伴</ion-button>
+          <ion-button>隐私政策</ion-button>
+        </ion-buttons>
+      </ion-toolbar>
+    </ion-footer> -->
 </ion-content>

+ 77 - 0
tailor-app/myapp/src/app/yiyun/yiyun.page.scss

@@ -0,0 +1,77 @@
+ion-searchbar {
+    --background: #ffffff; // 背景颜色
+    --placeholder-color: #aaaaaa; // 占位符颜色
+    --text-color: #000000; // 文本颜色
+    --border-color: #cccccc; // 边框颜色
+    --border-radius: 15px; // 边框圆角
+    --box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); // 阴影效果
+    // 你可以添加更多的CSS变量来定制样式
+  }
+  .button-container {
+    text-align: center;
+    padding: 16px;
+    border-radius: 8px;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    transition: all 0.3s ease;
+  }
+   
+  .button-container:hover {
+    transform: translateY(-4px);
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
+  }
+   
+  .item-image {
+    width: 100%;
+    height: auto;
+    border-radius: 8px 8px 0 0;
+  }
+   
+  .item-text {
+    margin-top: 0px;
+    font-size: 14px;
+    color: #333;
+  }
+  .custom-padding .button-container {
+    padding: 0px;
+    box-shadow: none;
+  }
+  ion-content {
+    --background: rgb(231, 244, 247);
+  }
+  // ion-avatar{
+  //   position: absolute;
+  //   top: 0;
+  // }
+  
+  ion-toolbar {
+    --background:rgb(231, 244, 247);;; /* 使用CSS变量设置背景色 */
+  }
+  ion-grid {
+    padding: 5px;
+  }
+  
+  ion-col {
+    width: 50%; // Adjust the width based on the number of columns you want
+  }
+  
+  ion-card {
+    margin-bottom: 10px;
+  }
+  
+  // You can use media queries to adjust the column width on different screen sizes
+  @media (min-width: 576px) {
+    ion-col {
+      min-height: 200px; // 较小屏幕下,设置一个最小高度,让布局看起来更规整
+    }
+  }
+
+  @media (min-width: 768px) {
+    ion-col {
+      min-height: 250px; // 中等屏幕下,适当增加最小高度
+    }
+  }
+
+  @media (min-width: 992px) {
+    ion-col {
+      min-height: 300px; // 大屏幕下,再增加最小高度,使布局更有瀑布流错落感
+    }}

+ 29 - 29
tailor-app/myapp/src/app/yiyun/yiyun.page.ts

@@ -1,48 +1,48 @@
 import { Component, NgModule, OnInit } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
-import { IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
-import { IonItem } from '@ionic/angular/standalone';
-import { IonList } from '@ionic/angular/standalone';
-import { IonSearchbar } from '@ionic/angular/standalone';
+import { ItemReorderEventDetail } from '@ionic/angular/standalone';
+import { addIcons } from 'ionicons';
+import { camera,trendingUpOutline,sparklesOutline,cloudyOutline,diceOutline} from 'ionicons/icons';
+import { IonContent, IonHeader, IonTitle, IonToolbar, IonButton, IonLabel, IonItem, IonList, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemOption, IonItemSliding, IonInput, IonCheckbox, IonRadio, IonToggle, IonRadioGroup, IonSearchbar,IonSegment,IonSegmentButton,IonDatetime,IonFooter,IonCardContent,IonCardTitle,IonCardHeader,IonCard,IonCol,IonRow,IonGrid,IonChip,IonImg } from '@ionic/angular/standalone';
+addIcons({camera,trendingUpOutline,sparklesOutline,cloudyOutline,diceOutline})
 @Component({
   selector: 'app-yiyun',
   templateUrl: './yiyun.page.html',
   styleUrls: ['./yiyun.page.scss'],
   standalone: true,
-  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule,IonItem,IonList,IonSearchbar]
+  imports: [IonContent, IonHeader, IonTitle, IonToolbar, CommonModule, FormsModule, IonButton,  IonLabel, IonLabel, IonList, IonItem, IonBackButton, IonButtons, IonIcon, IonItemDivider, IonAvatar, IonThumbnail, IonItemOptions, IonItemSliding, IonItemOption, IonItemOptions,IonInput,IonCheckbox,IonRadio,IonToggle,IonRadioGroup,IonSearchbar,IonSegment,IonSegmentButton,IonDatetime,IonFooter,IonCardContent,IonCardTitle,IonCardHeader,IonCard,IonCol,IonRow,IonGrid,IonChip,IonImg ]
+
 })
 
+
 export class YiyunPage implements OnInit {
 
   constructor() { }
 
   ngOnInit() {
   }
-  items: string[] = [
-    'Apple',
-    'Banana',
-    'Cherry',
-    'Date',
-    'Elderberry',
-    'Fig',
-    'Grape',
-    'Honeydew',
-    'Kiwi',
-    'Lemon'
+  public items = [
+    { text: '趋势分析', image: 'trending-up-outline', page: '/page1' },
+    { text: 'AI定制', image: 'dice-outline', page: '/page2' },
+    { text: '活动优惠', image: 'sparkles-outline', page: '/page3' },
+    { text: '虚拟试衣', image: 'cloudy-outline', page: '/page4' },
+    
   ];
- 
-  filteredItems: string[] = [...this.items];
- 
- 
-  onSearchInput(event: CustomEvent<any>) {
-    const searchValue = event.detail.value.toLowerCase();
-    if (!searchValue) {
-      this.filteredItems = [...this.items];
-    } else {
-      this.filteredItems = this.items.filter(item =>
-        item.toLowerCase().includes(searchValue)
-      );
-    }
+
+  products: any[] = [
+    { image: 'assets/img/shi.png', name: '商品1', description: '这是一个商品描述', price: 99.99 },
+    { image: 'assets/img/shi.png', name: '商品2', description: '这是一个商品描述', price: 199.99 },
+    { image: 'assets/img/shi.png', name: '商品1', description: '这是一个商品描述', price: 99.99 },
+    { image: 'assets/img/shi.png', name: '商品2', description: '这是一个商品描述', price: 199.99 },
+
+    // ... 更多商品数据
+  ];
+
+
+  // 打开登陆页面
+  openLoginModal(){
+    console.log("打开登陆页面");
+    
   }
 }

BIN
tailor-app/myapp/src/assets/img/3d.png


BIN
tailor-app/myapp/src/assets/img/ai2.png


BIN
tailor-app/myapp/src/assets/img/ding.png


BIN
tailor-app/myapp/src/assets/img/ding2.png


BIN
tailor-app/myapp/src/assets/img/jj.png


BIN
tailor-app/myapp/src/assets/img/shi.png


BIN
tailor-app/myapp/src/assets/img/yi2.png


+ 14 - 1
tailor-app/myapp/src/main.ts

@@ -4,11 +4,24 @@ import { IonicRouteStrategy, provideIonicAngular } from '@ionic/angular/standalo
 
 import { routes } from './app/app.routes';
 import { AppComponent } from './app/app.component';
-
+// let token = "r:16cd8f27084ff647fcdb5308a6783c4c"
+// 引用HttpClient方法
+import { provideHttpClient } from '@angular/common/http';
+// 引用移动端授权检测供应器
+import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
+// 设置Parse服务属性
+import Parse from "parse";
+Parse.initialize("ncloudmaster");
+Parse.serverURL = "https://server.fmode.cn/parse";
+localStorage.setItem("NOVA_APIG_SERVER", 'aHR0cHMlM0ElMkYlMkZzZXJ2ZXIuZm1vZGUuY24lMkZhcGklMkZhcGlnJTJG')
+Parse.User.become("r:16cd8f27084ff647fcdb5308a6783c4c")
 bootstrapApplication(AppComponent, {
   providers: [
     { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
     provideIonicAngular(),
     provideRouter(routes, withPreloading(PreloadAllModules)),
+    provideHttpClient(),
+    // 添加Diagnostic
+    Diagnostic,
   ],
 });

+ 2 - 1
tailor-app/myapp/tsconfig.json

@@ -19,7 +19,8 @@
     "target": "es2022",
     "module": "es2020",
     "lib": ["es2018", "dom"],
-    "useDefineForClassFields": false
+    "useDefineForClassFields": false,
+    "allowSyntheticDefaultImports":true
   },
   "angularCompilerOptions": {
     "enableI18nLegacyMessageIdFormat": false,

BIN
tailor-prod/衣韵智裁项目开题演讲.pptx


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác