Browse Source

fix:class

yf 3 months ago
parent
commit
bebbf584ee
64 changed files with 1568 additions and 1568 deletions
  1. 2 2
      .vscode/settings.json
  2. 18 18
      README.md
  3. 16 16
      dream-app/.browserslistrc
  4. 16 16
      dream-app/.editorconfig
  5. 46 46
      dream-app/.eslintrc.json
  6. 70 70
      dream-app/.gitignore
  7. 5 5
      dream-app/.vscode/extensions.json
  8. 3 3
      dream-app/.vscode/settings.json
  9. 9 9
      dream-app/capacitor.config.ts
  10. 7 7
      dream-app/ionic.config.json
  11. 44 44
      dream-app/karma.conf.js
  12. 3 3
      dream-app/src/app/app.component.html
  13. 16 16
      dream-app/src/app/app.component.spec.ts
  14. 12 12
      dream-app/src/app/app.component.ts
  15. 8 8
      dream-app/src/app/app.routes.ts
  16. 7 7
      dream-app/src/app/components/edit-rating-star/edit-rating-star.component.html
  17. 9 9
      dream-app/src/app/components/edit-rating-star/edit-rating-star.component.scss
  18. 22 22
      dream-app/src/app/components/edit-rating-star/edit-rating-star.component.spec.ts
  19. 55 55
      dream-app/src/app/components/edit-rating-star/edit-rating-star.component.ts
  20. 2 2
      dream-app/src/app/components/edit-tag/README.md
  21. 7 7
      dream-app/src/app/components/edit-tag/edit-tag.component.html
  22. 22 22
      dream-app/src/app/components/edit-tag/edit-tag.component.spec.ts
  23. 45 45
      dream-app/src/app/components/edit-tag/edit-tag.component.ts
  24. 12 12
      dream-app/src/app/explore-container/explore-container.component.html
  25. 26 26
      dream-app/src/app/explore-container/explore-container.component.scss
  26. 18 18
      dream-app/src/app/explore-container/explore-container.component.spec.ts
  27. 11 11
      dream-app/src/app/explore-container/explore-container.component.ts
  28. 19 19
      dream-app/src/app/page-dream-analysis/page-dream-analysis.component.html
  29. 22 22
      dream-app/src/app/page-dream-analysis/page-dream-analysis.component.spec.ts
  30. 127 127
      dream-app/src/app/page-dream-analysis/page-dream-analysis.component.ts
  31. 97 97
      dream-app/src/app/page-dream-analysis/test-chat-completion.ts
  32. 3 3
      dream-app/src/app/page-rxjs/page-rxjs.component.html
  33. 22 22
      dream-app/src/app/page-rxjs/page-rxjs.component.spec.ts
  34. 19 19
      dream-app/src/app/page-rxjs/page-rxjs.component.ts
  35. 17 17
      dream-app/src/app/page-test/page-test.component.html
  36. 22 22
      dream-app/src/app/page-test/page-test.component.spec.ts
  37. 36 36
      dream-app/src/app/page-test/page-test.component.ts
  38. 20 20
      dream-app/src/app/tab1/tab1.page.scss
  39. 22 22
      dream-app/src/app/tab1/tab1.page.spec.ts
  40. 17 17
      dream-app/src/app/tab2/tab2.page.html
  41. 18 18
      dream-app/src/app/tab2/tab2.page.spec.ts
  42. 16 16
      dream-app/src/app/tab2/tab2.page.ts
  43. 17 17
      dream-app/src/app/tab3/tab3.page.html
  44. 18 18
      dream-app/src/app/tab3/tab3.page.spec.ts
  45. 14 14
      dream-app/src/app/tab3/tab3.page.ts
  46. 20 20
      dream-app/src/app/tabs/tabs.page.html
  47. 1 1
      dream-app/src/app/tabs/tabs.page.scss
  48. 22 22
      dream-app/src/app/tabs/tabs.page.spec.ts
  49. 1 1
      dream-app/src/assets/shapes.svg
  50. 3 3
      dream-app/src/environments/environment.prod.ts
  51. 16 16
      dream-app/src/environments/environment.ts
  52. 37 37
      dream-app/src/global.scss
  53. 26 26
      dream-app/src/index.html
  54. 14 14
      dream-app/src/main.ts
  55. 55 55
      dream-app/src/polyfills.ts
  56. 14 14
      dream-app/src/test.ts
  57. 2 2
      dream-app/src/theme/variables.scss
  58. 6 6
      dream-app/src/zone-flags.ts
  59. 15 15
      dream-app/tsconfig.app.json
  60. 30 30
      dream-app/tsconfig.json
  61. 18 18
      dream-app/tsconfig.spec.json
  62. 143 143
      dream-prod/README.md
  63. 38 38
      dream-prod/image/产品信息图.md
  64. 70 70
      dream-prod/image/产品结构图.md

+ 2 - 2
.vscode/settings.json

@@ -1,3 +1,3 @@
-{
-    "plantuml.server":"http://www.plantuml.com/plantuml"
+{
+    "plantuml.server":"http://www.plantuml.com/plantuml"
 }

+ 18 - 18
README.md

@@ -1,19 +1,19 @@
-
-# 好梦(good dream)项目仓库
-
-# 项目结构
-- dream-prod/ 产品文档
-- dream-app/ 前端App项目
-
-# 前端项目开发常用指令
-
-``` bash
-# 打开前端代码目录
-cd dream-app
-
-# 安装前端第三方包依赖
-npm install
-
-# 启动Ionic项目,进行调试
-ionic serve
+
+# 好梦(good dream)项目仓库
+
+# 项目结构
+- dream-prod/ 产品文档
+- dream-app/ 前端App项目
+
+# 前端项目开发常用指令
+
+``` bash
+# 打开前端代码目录
+cd dream-app
+
+# 安装前端第三方包依赖
+npm install
+
+# 启动Ionic项目,进行调试
+ionic serve
 ```

+ 16 - 16
dream-app/.browserslistrc

@@ -1,16 +1,16 @@
-# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
-# For additional information regarding the format and rule options, please see:
-# https://github.com/browserslist/browserslist#queries
-
-# For the full list of supported browsers by the Angular framework, please see:
-# https://angular.io/guide/browser-support
-
-# You can see what browsers were selected by your queries by running:
-#   npx browserslist
-
-Chrome >=79
-ChromeAndroid >=79
-Firefox >=70
-Edge >=79
-Safari >=14
-iOS >=14
+# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
+# For additional information regarding the format and rule options, please see:
+# https://github.com/browserslist/browserslist#queries
+
+# For the full list of supported browsers by the Angular framework, please see:
+# https://angular.io/guide/browser-support
+
+# You can see what browsers were selected by your queries by running:
+#   npx browserslist
+
+Chrome >=79
+ChromeAndroid >=79
+Firefox >=70
+Edge >=79
+Safari >=14
+iOS >=14

+ 16 - 16
dream-app/.editorconfig

@@ -1,16 +1,16 @@
-# Editor configuration, see https://editorconfig.org
-root = true
-
-[*]
-charset = utf-8
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[*.ts]
-quote_type = single
-
-[*.md]
-max_line_length = off
-trim_trailing_whitespace = false
+# Editor configuration, see https://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.ts]
+quote_type = single
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false

+ 46 - 46
dream-app/.eslintrc.json

@@ -1,46 +1,46 @@
-{
-  "root": true,
-  "ignorePatterns": ["projects/**/*"],
-  "overrides": [
-    {
-      "files": ["*.ts"],
-      "parserOptions": {
-        "project": ["tsconfig.json"],
-        "createDefaultProgram": true
-      },
-      "extends": [
-        "plugin:@angular-eslint/recommended",
-        "plugin:@angular-eslint/template/process-inline-templates"
-      ],
-      "rules": {
-        "@angular-eslint/component-class-suffix": [
-          "error",
-          {
-            "suffixes": ["Page", "Component"]
-          }
-        ],
-        "@angular-eslint/component-selector": [
-          "error",
-          {
-            "type": "element",
-            "prefix": "app",
-            "style": "kebab-case"
-          }
-        ],
-        "@angular-eslint/directive-selector": [
-          "error",
-          {
-            "type": "attribute",
-            "prefix": "app",
-            "style": "camelCase"
-          }
-        ]
-      }
-    },
-    {
-      "files": ["*.html"],
-      "extends": ["plugin:@angular-eslint/template/recommended"],
-      "rules": {}
-    }
-  ]
-}
+{
+  "root": true,
+  "ignorePatterns": ["projects/**/*"],
+  "overrides": [
+    {
+      "files": ["*.ts"],
+      "parserOptions": {
+        "project": ["tsconfig.json"],
+        "createDefaultProgram": true
+      },
+      "extends": [
+        "plugin:@angular-eslint/recommended",
+        "plugin:@angular-eslint/template/process-inline-templates"
+      ],
+      "rules": {
+        "@angular-eslint/component-class-suffix": [
+          "error",
+          {
+            "suffixes": ["Page", "Component"]
+          }
+        ],
+        "@angular-eslint/component-selector": [
+          "error",
+          {
+            "type": "element",
+            "prefix": "app",
+            "style": "kebab-case"
+          }
+        ],
+        "@angular-eslint/directive-selector": [
+          "error",
+          {
+            "type": "attribute",
+            "prefix": "app",
+            "style": "camelCase"
+          }
+        ]
+      }
+    },
+    {
+      "files": ["*.html"],
+      "extends": ["plugin:@angular-eslint/template/recommended"],
+      "rules": {}
+    }
+  ]
+}

+ 70 - 70
dream-app/.gitignore

@@ -1,70 +1,70 @@
-# Specifies intentionally untracked files to ignore when using Git
-# http://git-scm.com/docs/gitignore
-
-*~
-*.sw[mnpcod]
-.tmp
-*.tmp
-*.tmp.*
-UserInterfaceState.xcuserstate
-$RECYCLE.BIN/
-
-*.log
-log.txt
-
-
-/.sourcemaps
-/.versions
-/coverage
-
-# Ionic
-/.ionic
-/www
-/platforms
-/plugins
-
-# Compiled output
-/dist
-/tmp
-/out-tsc
-/bazel-out
-
-# Node
-/node_modules
-npm-debug.log
-yarn-error.log
-
-# IDEs and editors
-.idea/
-.project
-.classpath
-.c9/
-*.launch
-.settings/
-*.sublime-project
-*.sublime-workspace
-
-# Visual Studio Code
-.vscode/*
-!.vscode/settings.json
-!.vscode/tasks.json
-!.vscode/launch.json
-!.vscode/extensions.json
-.history/*
-
-
-# Miscellaneous
-/.angular
-/.angular/cache
-.sass-cache/
-/.nx
-/.nx/cache
-/connect.lock
-/coverage
-/libpeerconnection.log
-testem.log
-/typings
-
-# System files
-.DS_Store
-Thumbs.db
+# Specifies intentionally untracked files to ignore when using Git
+# http://git-scm.com/docs/gitignore
+
+*~
+*.sw[mnpcod]
+.tmp
+*.tmp
+*.tmp.*
+UserInterfaceState.xcuserstate
+$RECYCLE.BIN/
+
+*.log
+log.txt
+
+
+/.sourcemaps
+/.versions
+/coverage
+
+# Ionic
+/.ionic
+/www
+/platforms
+/plugins
+
+# Compiled output
+/dist
+/tmp
+/out-tsc
+/bazel-out
+
+# Node
+/node_modules
+npm-debug.log
+yarn-error.log
+
+# IDEs and editors
+.idea/
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-project
+*.sublime-workspace
+
+# Visual Studio Code
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+.history/*
+
+
+# Miscellaneous
+/.angular
+/.angular/cache
+.sass-cache/
+/.nx
+/.nx/cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+testem.log
+/typings
+
+# System files
+.DS_Store
+Thumbs.db

+ 5 - 5
dream-app/.vscode/extensions.json

@@ -1,5 +1,5 @@
-{
-    "recommendations": [
-      "ionic.ionic"
-    ]
-}
+{
+    "recommendations": [
+      "ionic.ionic"
+    ]
+}

+ 3 - 3
dream-app/.vscode/settings.json

@@ -1,3 +1,3 @@
-{
-  "typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular"]
-}
+{
+  "typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular"]
+}

+ 9 - 9
dream-app/capacitor.config.ts

@@ -1,9 +1,9 @@
-import type { CapacitorConfig } from '@capacitor/cli';
-
-const config: CapacitorConfig = {
-  appId: 'io.ionic.starter',
-  appName: 'dream-app',
-  webDir: 'www'
-};
-
-export default config;
+import type { CapacitorConfig } from '@capacitor/cli';
+
+const config: CapacitorConfig = {
+  appId: 'io.ionic.starter',
+  appName: 'dream-app',
+  webDir: 'www'
+};
+
+export default config;

+ 7 - 7
dream-app/ionic.config.json

@@ -1,7 +1,7 @@
-{
-  "name": "dream-app",
-  "integrations": {
-    "capacitor": {}
-  },
-  "type": "angular-standalone"
-}
+{
+  "name": "dream-app",
+  "integrations": {
+    "capacitor": {}
+  },
+  "type": "angular-standalone"
+}

+ 44 - 44
dream-app/karma.conf.js

@@ -1,44 +1,44 @@
-// Karma configuration file, see link for more information
-// https://karma-runner.github.io/1.0/config/configuration-file.html
-
-module.exports = function (config) {
-  config.set({
-    basePath: '',
-    frameworks: ['jasmine', '@angular-devkit/build-angular'],
-    plugins: [
-      require('karma-jasmine'),
-      require('karma-chrome-launcher'),
-      require('karma-jasmine-html-reporter'),
-      require('karma-coverage'),
-      require('@angular-devkit/build-angular/plugins/karma')
-    ],
-    client: {
-      jasmine: {
-        // you can add configuration options for Jasmine here
-        // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
-        // for example, you can disable the random execution with `random: false`
-        // or set a specific seed with `seed: 4321`
-      },
-      clearContext: false // leave Jasmine Spec Runner output visible in browser
-    },
-    jasmineHtmlReporter: {
-      suppressAll: true // removes the duplicated traces
-    },
-    coverageReporter: {
-      dir: require('path').join(__dirname, './coverage/app'),
-      subdir: '.',
-      reporters: [
-        { type: 'html' },
-        { type: 'text-summary' }
-      ]
-    },
-    reporters: ['progress', 'kjhtml'],
-    port: 9876,
-    colors: true,
-    logLevel: config.LOG_INFO,
-    autoWatch: true,
-    browsers: ['Chrome'],
-    singleRun: false,
-    restartOnFileChange: true
-  });
-};
+// Karma configuration file, see link for more information
+// https://karma-runner.github.io/1.0/config/configuration-file.html
+
+module.exports = function (config) {
+  config.set({
+    basePath: '',
+    frameworks: ['jasmine', '@angular-devkit/build-angular'],
+    plugins: [
+      require('karma-jasmine'),
+      require('karma-chrome-launcher'),
+      require('karma-jasmine-html-reporter'),
+      require('karma-coverage'),
+      require('@angular-devkit/build-angular/plugins/karma')
+    ],
+    client: {
+      jasmine: {
+        // you can add configuration options for Jasmine here
+        // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
+        // for example, you can disable the random execution with `random: false`
+        // or set a specific seed with `seed: 4321`
+      },
+      clearContext: false // leave Jasmine Spec Runner output visible in browser
+    },
+    jasmineHtmlReporter: {
+      suppressAll: true // removes the duplicated traces
+    },
+    coverageReporter: {
+      dir: require('path').join(__dirname, './coverage/app'),
+      subdir: '.',
+      reporters: [
+        { type: 'html' },
+        { type: 'text-summary' }
+      ]
+    },
+    reporters: ['progress', 'kjhtml'],
+    port: 9876,
+    colors: true,
+    logLevel: config.LOG_INFO,
+    autoWatch: true,
+    browsers: ['Chrome'],
+    singleRun: false,
+    restartOnFileChange: true
+  });
+};

+ 3 - 3
dream-app/src/app/app.component.html

@@ -1,3 +1,3 @@
-<ion-app>
-  <ion-router-outlet></ion-router-outlet>
-</ion-app>
+<ion-app>
+  <ion-router-outlet></ion-router-outlet>
+</ion-app>

+ 16 - 16
dream-app/src/app/app.component.spec.ts

@@ -1,16 +1,16 @@
-import { TestBed } from '@angular/core/testing';
-import { provideRouter } from '@angular/router';
-import { AppComponent } from './app.component';
-
-describe('AppComponent', () => {
-  it('should create the app', async () => {
-    await TestBed.configureTestingModule({
-      imports: [AppComponent],
-      providers: [provideRouter([])]
-    }).compileComponents();
-    
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.componentInstance;
-    expect(app).toBeTruthy();
-  });
-});
+import { TestBed } from '@angular/core/testing';
+import { provideRouter } from '@angular/router';
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+  it('should create the app', async () => {
+    await TestBed.configureTestingModule({
+      imports: [AppComponent],
+      providers: [provideRouter([])]
+    }).compileComponents();
+    
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.componentInstance;
+    expect(app).toBeTruthy();
+  });
+});

+ 12 - 12
dream-app/src/app/app.component.ts

@@ -1,12 +1,12 @@
-import { Component } from '@angular/core';
-import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
-
-@Component({
-  selector: 'app-root',
-  templateUrl: 'app.component.html',
-  standalone: true,
-  imports: [IonApp, IonRouterOutlet],
-})
-export class AppComponent {
-  constructor() {}
-}
+import { Component } from '@angular/core';
+import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
+
+@Component({
+  selector: 'app-root',
+  templateUrl: 'app.component.html',
+  standalone: true,
+  imports: [IonApp, IonRouterOutlet],
+})
+export class AppComponent {
+  constructor() {}
+}

+ 8 - 8
dream-app/src/app/app.routes.ts

@@ -1,8 +1,8 @@
-import { Routes } from '@angular/router';
-
-export const routes: Routes = [
-  {
-    path: '',
-    loadChildren: () => import('./tabs/tabs.routes').then((m) => m.routes),
-  },
-];
+import { Routes } from '@angular/router';
+
+export const routes: Routes = [
+  {
+    path: '',
+    loadChildren: () => import('./tabs/tabs.routes').then((m) => m.routes),
+  },
+];

+ 7 - 7
dream-app/src/app/components/edit-rating-star/edit-rating-star.component.html

@@ -1,8 +1,8 @@
-<div class="star-rating">
-    <ng-container *ngFor="let star of starList; let i = index">
-      <ion-icon 
-        [name]="star ? 'star' : 'star-outline'" 
-        (click)="rate(i)">
-      </ion-icon>
-    </ng-container>
+<div class="star-rating">
+    <ng-container *ngFor="let star of starList; let i = index">
+      <ion-icon 
+        [name]="star ? 'star' : 'star-outline'" 
+        (click)="rate(i)">
+      </ion-icon>
+    </ng-container>
   </div>

+ 9 - 9
dream-app/src/app/components/edit-rating-star/edit-rating-star.component.scss

@@ -1,10 +1,10 @@
-.star-rating {
-    display: flex;
-    cursor: pointer;
-  
-    ion-icon {
-      font-size: 30px; // 调整星星大小
-      color: gold; // 星星颜色
-      margin-right: 5px; // 星星间距
-    }
+.star-rating {
+    display: flex;
+    cursor: pointer;
+  
+    ion-icon {
+      font-size: 30px; // 调整星星大小
+      color: gold; // 星星颜色
+      margin-right: 5px; // 星星间距
+    }
   }

+ 22 - 22
dream-app/src/app/components/edit-rating-star/edit-rating-star.component.spec.ts

@@ -1,22 +1,22 @@
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
-
-import { EditRatingStarComponent } from './edit-rating-star.component';
-
-describe('EditRatingStarComponent', () => {
-  let component: EditRatingStarComponent;
-  let fixture: ComponentFixture<EditRatingStarComponent>;
-
-  beforeEach(waitForAsync(() => {
-    TestBed.configureTestingModule({
-      imports: [EditRatingStarComponent],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(EditRatingStarComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  }));
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { EditRatingStarComponent } from './edit-rating-star.component';
+
+describe('EditRatingStarComponent', () => {
+  let component: EditRatingStarComponent;
+  let fixture: ComponentFixture<EditRatingStarComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [EditRatingStarComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(EditRatingStarComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 55 - 55
dream-app/src/app/components/edit-rating-star/edit-rating-star.component.ts

@@ -1,55 +1,55 @@
-import { Component, OnInit } from '@angular/core';
-import { Input, Output, EventEmitter } from '@angular/core';
-import { IonIcon } from '@ionic/angular/standalone';
-import { CommonModule } from '@angular/common';
-import { addIcons } from 'ionicons';
-import { star } from 'ionicons/icons';
-import { starOutline } from 'ionicons/icons';
-addIcons({star,starOutline})
-
-@Component({
-  selector: 'edit-rating-star',
-  templateUrl: './edit-rating-star.component.html',
-  styleUrls: ['./edit-rating-star.component.scss'],
-  imports:[IonIcon,CommonModule],
-  standalone: true,
-})
-export class EditRatingStarComponent  implements OnInit {
-  @Input() score: number = 0; // 默认分值为0
-  @Input() scoreMax: number = 5; // 最大分值
-  starList: boolean[] = []; // 星星状态数组
-
-  @Output() onScoreChange: EventEmitter<number> = new EventEmitter<number>();
-
-  constructor() {
-    this.updateStarList();
-  }
-
-  ngOnInit(){
-    this.updateStarList();
-  }
-  ngOnChanges() {
-    this.updateStarList();
-  }
-
-  // 更新星星数组
-  private updateStarList() {
-    this.starList = Array(this.scoreMax).fill(false);
-    for (let i = 0; i < this.score; i++) {
-      this.starList[i] = true;
-    }
-  }
-
-  // 打分方法
-  rate(index: number) {
-    if (this.score === index + 1) {
-      // 如果点击的是当前分值,清零
-      this.score = 0;
-    } else {
-      // 否则更新分值
-      this.score = index + 1;
-    }
-    this.updateStarList();
-    this.onScoreChange.emit(this.score); // 触发分值变化事件
-  }
-}
+import { Component, OnInit } from '@angular/core';
+import { Input, Output, EventEmitter } from '@angular/core';
+import { IonIcon } from '@ionic/angular/standalone';
+import { CommonModule } from '@angular/common';
+import { addIcons } from 'ionicons';
+import { star } from 'ionicons/icons';
+import { starOutline } from 'ionicons/icons';
+addIcons({star,starOutline})
+
+@Component({
+  selector: 'edit-rating-star',
+  templateUrl: './edit-rating-star.component.html',
+  styleUrls: ['./edit-rating-star.component.scss'],
+  imports:[IonIcon,CommonModule],
+  standalone: true,
+})
+export class EditRatingStarComponent  implements OnInit {
+  @Input() score: number = 0; // 默认分值为0
+  @Input() scoreMax: number = 5; // 最大分值
+  starList: boolean[] = []; // 星星状态数组
+
+  @Output() onScoreChange: EventEmitter<number> = new EventEmitter<number>();
+
+  constructor() {
+    this.updateStarList();
+  }
+
+  ngOnInit(){
+    this.updateStarList();
+  }
+  ngOnChanges() {
+    this.updateStarList();
+  }
+
+  // 更新星星数组
+  private updateStarList() {
+    this.starList = Array(this.scoreMax).fill(false);
+    for (let i = 0; i < this.score; i++) {
+      this.starList[i] = true;
+    }
+  }
+
+  // 打分方法
+  rate(index: number) {
+    if (this.score === index + 1) {
+      // 如果点击的是当前分值,清零
+      this.score = 0;
+    } else {
+      // 否则更新分值
+      this.score = index + 1;
+    }
+    this.updateStarList();
+    this.onScoreChange.emit(this.score); // 触发分值变化事件
+  }
+}

+ 2 - 2
dream-app/src/app/components/edit-tag/README.md

@@ -1,3 +1,3 @@
-# 标签编辑组件
-- 上面:输入框,和确认按钮
+# 标签编辑组件
+- 上面:输入框,和确认按钮
 - 下面:字符串数组,每个字符串是一个标签

+ 7 - 7
dream-app/src/app/components/edit-tag/edit-tag.component.html

@@ -1,8 +1,8 @@
-
-<ion-input [value]="userInputText" (ionInput)="userInput($event)" type="text" placeholder="请输入标签"></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>
+
+<ion-input [value]="userInputText" (ionInput)="userInput($event)" type="text" placeholder="请输入标签"></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>
 }

+ 22 - 22
dream-app/src/app/components/edit-tag/edit-tag.component.spec.ts

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

+ 45 - 45
dream-app/src/app/components/edit-tag/edit-tag.component.ts

@@ -1,45 +1,45 @@
-import { Component, OnInit,Output, EventEmitter } from '@angular/core';
-import { IonInput,IonButton,IonChip } from '@ionic/angular/standalone';
-
-@Component({
-  selector: 'app-edit-tag',
-  templateUrl: './edit-tag.component.html',
-  styleUrls: ['./edit-tag.component.scss'],
-  imports:[
-    IonInput,IonButton,IonChip
-  ],
-  standalone: true,
-})
-export class EditTagComponent  implements OnInit {
-  
-  /**
-   * 用户输入
-   */
-  userInputText:string = ""
-  userInput(ev:any){
-    console.log(ev)
-    this.userInputText = ev.detail.value
-  }
-
-
-  /**
-   * 标签列表
-   */
-  tags:Array<string> = []
-  addTag(){
-    this.tags.push(this.userInputText)
-    this.userInputText = ""
-    this.onTagChange.emit(this.tags)
-  }
-  deleteTag(tag:string){
-    let idx = this.tags.findIndex(item=>item==tag);
-    this.tags.splice(idx,1);
-  }
-  @Output()
-  onTagChange:EventEmitter<Array<string>> = new EventEmitter<Array<string>>()
-
-  constructor() { }
-
-  ngOnInit() {}
-
-}
+import { Component, OnInit,Output, EventEmitter } from '@angular/core';
+import { IonInput,IonButton,IonChip } from '@ionic/angular/standalone';
+
+@Component({
+  selector: 'app-edit-tag',
+  templateUrl: './edit-tag.component.html',
+  styleUrls: ['./edit-tag.component.scss'],
+  imports:[
+    IonInput,IonButton,IonChip
+  ],
+  standalone: true,
+})
+export class EditTagComponent  implements OnInit {
+  
+  /**
+   * 用户输入
+   */
+  userInputText:string = ""
+  userInput(ev:any){
+    console.log(ev)
+    this.userInputText = ev.detail.value
+  }
+
+
+  /**
+   * 标签列表
+   */
+  tags:Array<string> = []
+  addTag(){
+    this.tags.push(this.userInputText)
+    this.userInputText = ""
+    this.onTagChange.emit(this.tags)
+  }
+  deleteTag(tag:string){
+    let idx = this.tags.findIndex(item=>item==tag);
+    this.tags.splice(idx,1);
+  }
+  @Output()
+  onTagChange:EventEmitter<Array<string>> = new EventEmitter<Array<string>>()
+
+  constructor() { }
+
+  ngOnInit() {}
+
+}

+ 12 - 12
dream-app/src/app/explore-container/explore-container.component.html

@@ -1,12 +1,12 @@
-<div id="container">
-  <strong>{{ name }}</strong>
-  <p>
-    Explore
-    <a
-      target="_blank"
-      rel="noopener noreferrer"
-      href="https://ionicframework.com/docs/components"
-      >UI Components</a
-    >
-  </p>
-</div>
+<div id="container">
+  <strong>{{ name }}</strong>
+  <p>
+    Explore
+    <a
+      target="_blank"
+      rel="noopener noreferrer"
+      href="https://ionicframework.com/docs/components"
+      >UI Components</a
+    >
+  </p>
+</div>

+ 26 - 26
dream-app/src/app/explore-container/explore-container.component.scss

@@ -1,27 +1,27 @@
-#container {
-  text-align: center;
-
-  position: absolute;
-  left: 0;
-  right: 0;
-  top: 50%;
-  transform: translateY(-50%);
-}
-
-#container strong {
-  font-size: 20px;
-  line-height: 26px;
-}
-
-#container p {
-  font-size: 16px;
-  line-height: 22px;
-
-  color: #8c8c8c;
-
-  margin: 0;
-}
-
-#container a {
-  text-decoration: none;
+#container {
+  text-align: center;
+
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+#container strong {
+  font-size: 20px;
+  line-height: 26px;
+}
+
+#container p {
+  font-size: 16px;
+  line-height: 22px;
+
+  color: #8c8c8c;
+
+  margin: 0;
+}
+
+#container a {
+  text-decoration: none;
 }

+ 18 - 18
dream-app/src/app/explore-container/explore-container.component.spec.ts

@@ -1,18 +1,18 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { ExploreContainerComponent } from './explore-container.component';
-
-describe('ExploreContainerComponent', () => {
-  let component: ExploreContainerComponent;
-  let fixture: ComponentFixture<ExploreContainerComponent>;
-
-  beforeEach(async () => {
-    fixture = TestBed.createComponent(ExploreContainerComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ExploreContainerComponent } from './explore-container.component';
+
+describe('ExploreContainerComponent', () => {
+  let component: ExploreContainerComponent;
+  let fixture: ComponentFixture<ExploreContainerComponent>;
+
+  beforeEach(async () => {
+    fixture = TestBed.createComponent(ExploreContainerComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 11 - 11
dream-app/src/app/explore-container/explore-container.component.ts

@@ -1,11 +1,11 @@
-import { Component, Input } from '@angular/core';
-
-@Component({
-  selector: 'app-explore-container',
-  templateUrl: './explore-container.component.html',
-  styleUrls: ['./explore-container.component.scss'],
-  standalone: true,
-})
-export class ExploreContainerComponent {
-  @Input() name?: string;
-}
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'app-explore-container',
+  templateUrl: './explore-container.component.html',
+  styleUrls: ['./explore-container.component.scss'],
+  standalone: true,
+})
+export class ExploreContainerComponent {
+  @Input() name?: string;
+}

+ 19 - 19
dream-app/src/app/page-dream-analysis/page-dream-analysis.component.html

@@ -1,20 +1,20 @@
-
-<ion-list>
-  <ion-item>
-    梦境标签
-  </ion-item>
-  <ion-item>
-      <app-edit-tag (onTagChange)="setTagsValue($event)"></app-edit-tag>
-  </ion-item>
-  <ion-item>
-    <ion-textarea [value]="dreamDesc" (ionInput)="userInput($event)" label="梦境描述" placeholder="具体描述您的感受、场景、人物、物品、事件" [autoGrow]="true"></ion-textarea>
-  </ion-item>
-  <ion-item>
-      <ion-button expand="block" (click)="analysisDream()">解析梦境</ion-button>
-  </ion-item>
-  <ion-item>
-    {{dreamResult}}
-  </ion-item>
-</ion-list>
-<!-- <div style="font-size: 18px">
+
+<ion-list>
+  <ion-item>
+    梦境标签
+  </ion-item>
+  <ion-item>
+      <app-edit-tag (onTagChange)="setTagsValue($event)"></app-edit-tag>
+  </ion-item>
+  <ion-item>
+    <ion-textarea [value]="dreamDesc" (ionInput)="userInput($event)" label="梦境描述" placeholder="具体描述您的感受、场景、人物、物品、事件" [autoGrow]="true"></ion-textarea>
+  </ion-item>
+  <ion-item>
+      <ion-button expand="block" (click)="analysisDream()">解析梦境</ion-button>
+  </ion-item>
+  <ion-item>
+    {{dreamResult}}
+  </ion-item>
+</ion-list>
+<!-- <div style="font-size: 18px">
 </div> -->

+ 22 - 22
dream-app/src/app/page-dream-analysis/page-dream-analysis.component.spec.ts

@@ -1,22 +1,22 @@
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
-
-import { PageDreamAnalysisComponent } from './page-dream-analysis.component';
-
-describe('PageDreamAnalysisComponent', () => {
-  let component: PageDreamAnalysisComponent;
-  let fixture: ComponentFixture<PageDreamAnalysisComponent>;
-
-  beforeEach(waitForAsync(() => {
-    TestBed.configureTestingModule({
-      imports: [PageDreamAnalysisComponent],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(PageDreamAnalysisComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  }));
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { PageDreamAnalysisComponent } from './page-dream-analysis.component';
+
+describe('PageDreamAnalysisComponent', () => {
+  let component: PageDreamAnalysisComponent;
+  let fixture: ComponentFixture<PageDreamAnalysisComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [PageDreamAnalysisComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(PageDreamAnalysisComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 127 - 127
dream-app/src/app/page-dream-analysis/page-dream-analysis.component.ts

@@ -1,127 +1,127 @@
-import { Component, OnInit } from '@angular/core';
-import { EditTagComponent } from '../components/edit-tag/edit-tag.component';
-import { IonList } from '@ionic/angular/standalone';
-import { IonItem, IonTextarea,IonButton } from '@ionic/angular/standalone';
-import { TestChatCompletion } from './test-chat-completion';
-// import { FmodeChatCompletion } from "fmode-ng";
-@Component({
-  selector: 'app-page-dream-analysis',
-  templateUrl: './page-dream-analysis.component.html',
-  styleUrls: ['./page-dream-analysis.component.scss'],
-  imports:[
-    EditTagComponent,
-    IonList,IonItem,IonTextarea,IonButton
-  ],
-  standalone: true,
-})
-export class PageDreamAnalysisComponent  implements OnInit {
-
-
-  // 梦境关键词
-  dreamTags:Array<string> = []
-  setTagsValue(ev:any){
-    this.dreamTags = ev;
-  }
-  // 梦境描述
-  dreamDesc:string = ""
-  userInput(ev:any){
-    this.dreamDesc = ev.detail.value
-  }
-
-  // 梦境结果
-  dreamResult:string = ""
-
-  // 解析梦境
-  async analysisDream(){
-    console.log("关键词",this.dreamTags)
-    console.log("描述",this.dreamDesc)
-    console.log("开始解析梦境")
-    let prompt = `您作为一名专业的梦境解析大师,请帮我解析以下梦境。关键词:${this.dreamTags.join(",")},梦境描述:${this.dreamDesc}`
-
-    let TOKEN = `r:e20ef91b23e2c21d45cb50cd5ec1a122`;
-    localStorage.setItem("token",TOKEN)
-
-    let messageList:any = [
-      {
-        role:"system",content:`${new Date().toLocaleString()}`
-      },
-      {
-        role:"user",content:prompt
-      }
-    ]
-
-    // 创建并发起一条新的消息补全
-    let completion = new TestChatCompletion(messageList)
-    // 持续更新事件推送的消息体内容绑定至消息变量
-    completion.createCompletionByStream()
-
-    setInterval(()=>{
-      console.log(messageList)
-      this.dreamDesc = 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"
-    // });
-    // if(response && response.body){
-
-    //   let reader = response.body.getReader();
-
-    //   if (!reader) {
-    //     throw new Error("Failed to get the response reader.");
-    //   }
-
-    //   let decoder = new TextDecoder();
-    
-    //   while (true) {
-    //     let { done, value } = await reader.read();
-    //     if (done) {
-    //       break;
-    //     }
-    
-    //     let data = decoder.decode(value);
-    //     /**
-    //       data: {"id":"chatcmpl-AXgfsaapykrm9oEBVQTwRZAVRQHj7","object":"chat.completion.chunk","created":1732592228,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0705bf87c0","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null}
-    //       data: {"id":"chatcmpl-AXgfsaapykrm9oEBVQTwRZAVRQHj7","object":"chat.completion.chunk","created":1732592228,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0705bf87c0","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null}
-    //       data: {"id":"chatcmpl-AXgfsaapykrm9oEBVQTwRZAVRQHj7","object":"chat.completion.chunk","created":1732592228,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0705bf87c0","choices":[],"usage":{"prompt_tokens":110,"completion_tokens":240,"total_tokens":350,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}}
-    //       data: [DONE]
-    //      */
-    //     let messages = data.split("\n");
-    //     messages.forEach(message=>{
-    //       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
-    //           console.log(content)
-    //           this.dreamResult =  this.dreamResult + content
-    //         }catch(err){}
-    //       }
-    //     })
-
-    //   }
-    // }
-  }
-
-  constructor() { }
-
-  ngOnInit() {}
-
-}
+import { Component, OnInit } from '@angular/core';
+import { EditTagComponent } from '../components/edit-tag/edit-tag.component';
+import { IonList } from '@ionic/angular/standalone';
+import { IonItem, IonTextarea,IonButton } from '@ionic/angular/standalone';
+import { TestChatCompletion } from './test-chat-completion';
+// import { FmodeChatCompletion } from "fmode-ng";
+@Component({
+  selector: 'app-page-dream-analysis',
+  templateUrl: './page-dream-analysis.component.html',
+  styleUrls: ['./page-dream-analysis.component.scss'],
+  imports:[
+    EditTagComponent,
+    IonList,IonItem,IonTextarea,IonButton
+  ],
+  standalone: true,
+})
+export class PageDreamAnalysisComponent  implements OnInit {
+
+
+  // 梦境关键词
+  dreamTags:Array<string> = []
+  setTagsValue(ev:any){
+    this.dreamTags = ev;
+  }
+  // 梦境描述
+  dreamDesc:string = ""
+  userInput(ev:any){
+    this.dreamDesc = ev.detail.value
+  }
+
+  // 梦境结果
+  dreamResult:string = ""
+
+  // 解析梦境
+  async analysisDream(){
+    console.log("关键词",this.dreamTags)
+    console.log("描述",this.dreamDesc)
+    console.log("开始解析梦境")
+    let prompt = `您作为一名专业的梦境解析大师,请帮我解析以下梦境。关键词:${this.dreamTags.join(",")},梦境描述:${this.dreamDesc}`
+
+    let TOKEN = `r:e20ef91b23e2c21d45cb50cd5ec1a122`;
+    localStorage.setItem("token",TOKEN)
+
+    let messageList:any = [
+      {
+        role:"system",content:`${new Date().toLocaleString()}`
+      },
+      {
+        role:"user",content:prompt
+      }
+    ]
+
+    // 创建并发起一条新的消息补全
+    let completion = new TestChatCompletion(messageList)
+    // 持续更新事件推送的消息体内容绑定至消息变量
+    completion.createCompletionByStream()
+
+    setInterval(()=>{
+      console.log(messageList)
+      this.dreamDesc = 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"
+    // });
+    // if(response && response.body){
+
+    //   let reader = response.body.getReader();
+
+    //   if (!reader) {
+    //     throw new Error("Failed to get the response reader.");
+    //   }
+
+    //   let decoder = new TextDecoder();
+    
+    //   while (true) {
+    //     let { done, value } = await reader.read();
+    //     if (done) {
+    //       break;
+    //     }
+    
+    //     let data = decoder.decode(value);
+    //     /**
+    //       data: {"id":"chatcmpl-AXgfsaapykrm9oEBVQTwRZAVRQHj7","object":"chat.completion.chunk","created":1732592228,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0705bf87c0","choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null}
+    //       data: {"id":"chatcmpl-AXgfsaapykrm9oEBVQTwRZAVRQHj7","object":"chat.completion.chunk","created":1732592228,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0705bf87c0","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null}
+    //       data: {"id":"chatcmpl-AXgfsaapykrm9oEBVQTwRZAVRQHj7","object":"chat.completion.chunk","created":1732592228,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0705bf87c0","choices":[],"usage":{"prompt_tokens":110,"completion_tokens":240,"total_tokens":350,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}}
+    //       data: [DONE]
+    //      */
+    //     let messages = data.split("\n");
+    //     messages.forEach(message=>{
+    //       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
+    //           console.log(content)
+    //           this.dreamResult =  this.dreamResult + content
+    //         }catch(err){}
+    //       }
+    //     })
+
+    //   }
+    // }
+  }
+
+  constructor() { }
+
+  ngOnInit() {}
+
+}

+ 97 - 97
dream-app/src/app/page-dream-analysis/test-chat-completion.ts

@@ -1,98 +1,98 @@
-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/",
-  "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);
-  }
-}
-}
+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/",
+  "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 - 3
dream-app/src/app/page-rxjs/page-rxjs.component.html

@@ -1,3 +1,3 @@
-<p>
-  page-rxjs works!
-</p>
+<p>
+  page-rxjs works!
+</p>

+ 22 - 22
dream-app/src/app/page-rxjs/page-rxjs.component.spec.ts

@@ -1,22 +1,22 @@
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
-
-import { PageRxjsComponent } from './page-rxjs.component';
-
-describe('PageRxjsComponent', () => {
-  let component: PageRxjsComponent;
-  let fixture: ComponentFixture<PageRxjsComponent>;
-
-  beforeEach(waitForAsync(() => {
-    TestBed.configureTestingModule({
-      imports: [PageRxjsComponent],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(PageRxjsComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  }));
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { PageRxjsComponent } from './page-rxjs.component';
+
+describe('PageRxjsComponent', () => {
+  let component: PageRxjsComponent;
+  let fixture: ComponentFixture<PageRxjsComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [PageRxjsComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(PageRxjsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 19 - 19
dream-app/src/app/page-rxjs/page-rxjs.component.ts

@@ -1,19 +1,19 @@
-import { Component, OnInit } from '@angular/core';
-// import { from } from "rxjs"
-@Component({
-  selector: 'app-page-rxjs',
-  templateUrl: './page-rxjs.component.html',
-  styleUrls: ['./page-rxjs.component.scss'],
-  standalone: true,
-})
-export class PageRxjsComponent  implements OnInit {
-
-  constructor() { }
-
-  ngOnInit() {}
-
-  testRxjs(){
-    // from
-  }
-
-}
+import { Component, OnInit } from '@angular/core';
+// import { from } from "rxjs"
+@Component({
+  selector: 'app-page-rxjs',
+  templateUrl: './page-rxjs.component.html',
+  styleUrls: ['./page-rxjs.component.scss'],
+  standalone: true,
+})
+export class PageRxjsComponent  implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {}
+
+  testRxjs(){
+    // from
+  }
+
+}

+ 17 - 17
dream-app/src/app/page-test/page-test.component.html

@@ -1,18 +1,18 @@
-
-  <h1>星星打分组件演示:分值 {{currentScore}}</h1>
-  <edit-rating-star 
-    [score]="currentScore" 
-    [scoreMax]="5" 
-    (onScoreChange)="handleScoreChange($event)">
-  </edit-rating-star>
-  
-  <h1>编辑标签演示</h1>
-  <app-edit-tag (onTagChange)="setTagsValue($event)"></app-edit-tag>
-
-
-  <h1>父级页面:从子组件输出事件获取属性</h1>
-  <ul>
-    @for(tag of editTags;track tag;){
-      <li>{{tag}}</li>
-    }
+
+  <h1>星星打分组件演示:分值 {{currentScore}}</h1>
+  <edit-rating-star 
+    [score]="currentScore" 
+    [scoreMax]="5" 
+    (onScoreChange)="handleScoreChange($event)">
+  </edit-rating-star>
+  
+  <h1>编辑标签演示</h1>
+  <app-edit-tag (onTagChange)="setTagsValue($event)"></app-edit-tag>
+
+
+  <h1>父级页面:从子组件输出事件获取属性</h1>
+  <ul>
+    @for(tag of editTags;track tag;){
+      <li>{{tag}}</li>
+    }
   </ul>

+ 22 - 22
dream-app/src/app/page-test/page-test.component.spec.ts

@@ -1,22 +1,22 @@
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
-
-import { PageTestComponent } from './page-test.component';
-
-describe('PageTestComponent', () => {
-  let component: PageTestComponent;
-  let fixture: ComponentFixture<PageTestComponent>;
-
-  beforeEach(waitForAsync(() => {
-    TestBed.configureTestingModule({
-      imports: [PageTestComponent],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(PageTestComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  }));
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { PageTestComponent } from './page-test.component';
+
+describe('PageTestComponent', () => {
+  let component: PageTestComponent;
+  let fixture: ComponentFixture<PageTestComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [PageTestComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(PageTestComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 36 - 36
dream-app/src/app/page-test/page-test.component.ts

@@ -1,36 +1,36 @@
-import { Component, OnInit } from '@angular/core';
-import { EditTagComponent } from '../components/edit-tag/edit-tag.component';
-import { EditRatingStarComponent } from '../components/edit-rating-star/edit-rating-star.component';
-
-@Component({
-  selector: 'app-page-test',
-  templateUrl: './page-test.component.html',
-  styleUrls: ['./page-test.component.scss'],
-  standalone: true,
-  imports:[
-    EditTagComponent,EditRatingStarComponent
-  ]
-})
-export class PageTestComponent  implements OnInit {
-
-  constructor() { }
-
-  ngOnInit() {}
-
-   // 星星打分
-   currentScore: number = 0; // 初始分值
-
-   handleScoreChange(newScore: number) {
-     this.currentScore = newScore;
-     console.log('新分值:', newScore); // 处理分值变化
-   }
- 
-   // 编辑标签
-   editTags:Array<string> = []
-   setTagsValue(ev:any){
-     console.log("setTagsValue",ev)
-     this.editTags = ev;
-   }
-   
-
-}
+import { Component, OnInit } from '@angular/core';
+import { EditTagComponent } from '../components/edit-tag/edit-tag.component';
+import { EditRatingStarComponent } from '../components/edit-rating-star/edit-rating-star.component';
+
+@Component({
+  selector: 'app-page-test',
+  templateUrl: './page-test.component.html',
+  styleUrls: ['./page-test.component.scss'],
+  standalone: true,
+  imports:[
+    EditTagComponent,EditRatingStarComponent
+  ]
+})
+export class PageTestComponent  implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {}
+
+   // 星星打分
+   currentScore: number = 0; // 初始分值
+
+   handleScoreChange(newScore: number) {
+     this.currentScore = newScore;
+     console.log('新分值:', newScore); // 处理分值变化
+   }
+ 
+   // 编辑标签
+   editTags:Array<string> = []
+   setTagsValue(ev:any){
+     console.log("setTagsValue",ev)
+     this.editTags = ev;
+   }
+   
+
+}

+ 20 - 20
dream-app/src/app/tab1/tab1.page.scss

@@ -1,21 +1,21 @@
-.main-functions {
-    padding: 16px;
-  
-    ion-button {
-      margin-bottom: 16px;
-    }
-  
-    .function-cards {
-      display: flex;
-      flex-direction: row;
-      justify-content: space-between;
-  
-      ion-card {
-        width: 48%;
-      }
-    }
-  }
-  
-  ion-list {
-    margin-top: 16px;
+.main-functions {
+    padding: 16px;
+  
+    ion-button {
+      margin-bottom: 16px;
+    }
+  
+    .function-cards {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+  
+      ion-card {
+        width: 48%;
+      }
+    }
+  }
+  
+  ion-list {
+    margin-top: 16px;
   }

+ 22 - 22
dream-app/src/app/tab1/tab1.page.spec.ts

@@ -1,23 +1,23 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { Tab1Page } from './tab1.page';
-
-describe('Tab1Page', () => {
-  let component: Tab1Page;
-  let fixture: ComponentFixture<Tab1Page>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [Tab1Page],
-    }).compileComponents();
-  });
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(Tab1Page);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { Tab1Page } from './tab1.page';
+
+describe('Tab1Page', () => {
+  let component: Tab1Page;
+  let fixture: ComponentFixture<Tab1Page>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [Tab1Page],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(Tab1Page);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
 });

+ 17 - 17
dream-app/src/app/tab2/tab2.page.html

@@ -1,17 +1,17 @@
-<ion-header [translucent]="true">
-  <ion-toolbar>
-    <ion-title>
-      Tab 2
-    </ion-title>
-  </ion-toolbar>
-</ion-header>
-
-<ion-content [fullscreen]="true">
-  <ion-header collapse="condense">
-    <ion-toolbar>
-      <ion-title size="large">Tab 2</ion-title>
-    </ion-toolbar>
-  </ion-header>
-
-  <app-explore-container name="Tab 2 page"></app-explore-container>
-</ion-content>
+<ion-header [translucent]="true">
+  <ion-toolbar>
+    <ion-title>
+      Tab 2
+    </ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+  <ion-header collapse="condense">
+    <ion-toolbar>
+      <ion-title size="large">Tab 2</ion-title>
+    </ion-toolbar>
+  </ion-header>
+
+  <app-explore-container name="Tab 2 page"></app-explore-container>
+</ion-content>

+ 18 - 18
dream-app/src/app/tab2/tab2.page.spec.ts

@@ -1,18 +1,18 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { Tab2Page } from './tab2.page';
-
-describe('Tab2Page', () => {
-  let component: Tab2Page;
-  let fixture: ComponentFixture<Tab2Page>;
-
-  beforeEach(async () => {
-    fixture = TestBed.createComponent(Tab2Page);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { Tab2Page } from './tab2.page';
+
+describe('Tab2Page', () => {
+  let component: Tab2Page;
+  let fixture: ComponentFixture<Tab2Page>;
+
+  beforeEach(async () => {
+    fixture = TestBed.createComponent(Tab2Page);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 16 - 16
dream-app/src/app/tab2/tab2.page.ts

@@ -1,16 +1,16 @@
-import { Component } from '@angular/core';
-import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
-import { ExploreContainerComponent } from '../explore-container/explore-container.component';
-
-@Component({
-  selector: 'app-tab2',
-  templateUrl: 'tab2.page.html',
-  styleUrls: ['tab2.page.scss'],
-  standalone: true,
-  imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent]
-})
-export class Tab2Page {
-
-  constructor() {}
-
-}
+import { Component } from '@angular/core';
+import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
+import { ExploreContainerComponent } from '../explore-container/explore-container.component';
+
+@Component({
+  selector: 'app-tab2',
+  templateUrl: 'tab2.page.html',
+  styleUrls: ['tab2.page.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent]
+})
+export class Tab2Page {
+
+  constructor() {}
+
+}

+ 17 - 17
dream-app/src/app/tab3/tab3.page.html

@@ -1,17 +1,17 @@
-<ion-header [translucent]="true">
-  <ion-toolbar>
-    <ion-title>
-      Tab 3
-    </ion-title>
-  </ion-toolbar>
-</ion-header>
-
-<ion-content [fullscreen]="true">
-  <ion-header collapse="condense">
-    <ion-toolbar>
-      <ion-title size="large">Tab 3</ion-title>
-    </ion-toolbar>
-  </ion-header>
-
-  <app-explore-container name="Tab 3 page"></app-explore-container>
-</ion-content>
+<ion-header [translucent]="true">
+  <ion-toolbar>
+    <ion-title>
+      Tab 3
+    </ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+  <ion-header collapse="condense">
+    <ion-toolbar>
+      <ion-title size="large">Tab 3</ion-title>
+    </ion-toolbar>
+  </ion-header>
+
+  <app-explore-container name="Tab 3 page"></app-explore-container>
+</ion-content>

+ 18 - 18
dream-app/src/app/tab3/tab3.page.spec.ts

@@ -1,18 +1,18 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { Tab3Page } from './tab3.page';
-
-describe('Tab3Page', () => {
-  let component: Tab3Page;
-  let fixture: ComponentFixture<Tab3Page>;
-
-  beforeEach(async () => {
-    fixture = TestBed.createComponent(Tab3Page);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { Tab3Page } from './tab3.page';
+
+describe('Tab3Page', () => {
+  let component: Tab3Page;
+  let fixture: ComponentFixture<Tab3Page>;
+
+  beforeEach(async () => {
+    fixture = TestBed.createComponent(Tab3Page);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 14 - 14
dream-app/src/app/tab3/tab3.page.ts

@@ -1,14 +1,14 @@
-import { Component } from '@angular/core';
-import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
-import { ExploreContainerComponent } from '../explore-container/explore-container.component';
-
-@Component({
-  selector: 'app-tab3',
-  templateUrl: 'tab3.page.html',
-  styleUrls: ['tab3.page.scss'],
-  standalone: true,
-  imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent],
-})
-export class Tab3Page {
-  constructor() {}
-}
+import { Component } from '@angular/core';
+import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
+import { ExploreContainerComponent } from '../explore-container/explore-container.component';
+
+@Component({
+  selector: 'app-tab3',
+  templateUrl: 'tab3.page.html',
+  styleUrls: ['tab3.page.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent],
+})
+export class Tab3Page {
+  constructor() {}
+}

+ 20 - 20
dream-app/src/app/tabs/tabs.page.html

@@ -1,21 +1,21 @@
-<ion-tabs>
-  <ion-tab-bar slot="bottom">
-    <!-- 好梦 -->
-    <ion-tab-button tab="tab1" href="/tabs/tab1">
-      <ion-icon name="moon-outline"></ion-icon>
-      <ion-label>好梦</ion-label>
-    </ion-tab-button>
-
-    <!-- 探索 -->
-    <ion-tab-button tab="tab2" href="/tabs/tab2">
-      <ion-icon name="compass-outline"></ion-icon>
-      <ion-label>探索</ion-label>
-    </ion-tab-button>
-
-    <!-- 我的 -->
-    <ion-tab-button tab="tab3" href="/tabs/tab3">
-      <ion-icon name="person-outline"></ion-icon>
-      <ion-label>我的</ion-label>
-    </ion-tab-button>
-  </ion-tab-bar>
+<ion-tabs>
+  <ion-tab-bar slot="bottom">
+    <!-- 好梦 -->
+    <ion-tab-button tab="tab1" href="/tabs/tab1">
+      <ion-icon name="moon-outline"></ion-icon>
+      <ion-label>好梦</ion-label>
+    </ion-tab-button>
+
+    <!-- 探索 -->
+    <ion-tab-button tab="tab2" href="/tabs/tab2">
+      <ion-icon name="compass-outline"></ion-icon>
+      <ion-label>探索</ion-label>
+    </ion-tab-button>
+
+    <!-- 我的 -->
+    <ion-tab-button tab="tab3" href="/tabs/tab3">
+      <ion-icon name="person-outline"></ion-icon>
+      <ion-label>我的</ion-label>
+    </ion-tab-button>
+  </ion-tab-bar>
 </ion-tabs>

+ 1 - 1
dream-app/src/app/tabs/tabs.page.scss

@@ -1 +1 @@
-
+

+ 22 - 22
dream-app/src/app/tabs/tabs.page.spec.ts

@@ -1,23 +1,23 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { TabsPage } from './tabs.page';
-
-describe('TabsPage', () => {
-  let component: TabsPage;
-  let fixture: ComponentFixture<TabsPage>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      imports: [TabsPage],
-    }).compileComponents();
-  });
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(TabsPage);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { TabsPage } from './tabs.page';
+
+describe('TabsPage', () => {
+  let component: TabsPage;
+  let fixture: ComponentFixture<TabsPage>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [TabsPage],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(TabsPage);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
 });

+ 1 - 1
dream-app/src/assets/shapes.svg

@@ -1 +1 @@
-<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>
+<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

+ 3 - 3
dream-app/src/environments/environment.prod.ts

@@ -1,3 +1,3 @@
-export const environment = {
-  production: true
-};
+export const environment = {
+  production: true
+};

+ 16 - 16
dream-app/src/environments/environment.ts

@@ -1,16 +1,16 @@
-// This file can be replaced during build by using the `fileReplacements` array.
-// `ng build` replaces `environment.ts` with `environment.prod.ts`.
-// The list of file replacements can be found in `angular.json`.
-
-export const environment = {
-  production: false
-};
-
-/*
- * For easier debugging in development mode, you can import the following file
- * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
- *
- * This import should be commented out in production mode because it will have a negative impact
- * on performance if an error is thrown.
- */
-// import 'zone.js/plugins/zone-error';  // Included with Angular CLI.
+// This file can be replaced during build by using the `fileReplacements` array.
+// `ng build` replaces `environment.ts` with `environment.prod.ts`.
+// The list of file replacements can be found in `angular.json`.
+
+export const environment = {
+  production: false
+};
+
+/*
+ * For easier debugging in development mode, you can import the following file
+ * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
+ *
+ * This import should be commented out in production mode because it will have a negative impact
+ * on performance if an error is thrown.
+ */
+// import 'zone.js/plugins/zone-error';  // Included with Angular CLI.

+ 37 - 37
dream-app/src/global.scss

@@ -1,37 +1,37 @@
-/*
- * App Global CSS
- * ----------------------------------------------------------------------------
- * Put style rules here that you want to apply globally. These styles are for
- * the entire app and not just one component. Additionally, this file can be
- * used as an entry point to import other CSS/Sass files to be included in the
- * output CSS.
- * For more information on global stylesheets, visit the documentation:
- * https://ionicframework.com/docs/layout/global-stylesheets
- */
-
-/* Core CSS required for Ionic components to work properly */
-@import "@ionic/angular/css/core.css";
-
-/* Basic CSS for apps built with Ionic */
-@import "@ionic/angular/css/normalize.css";
-@import "@ionic/angular/css/structure.css";
-@import "@ionic/angular/css/typography.css";
-@import "@ionic/angular/css/display.css";
-
-/* Optional CSS utils that can be commented out */
-@import "@ionic/angular/css/padding.css";
-@import "@ionic/angular/css/float-elements.css";
-@import "@ionic/angular/css/text-alignment.css";
-@import "@ionic/angular/css/text-transformation.css";
-@import "@ionic/angular/css/flex-utils.css";
-
-/**
- * Ionic Dark Mode
- * -----------------------------------------------------
- * For more info, please see:
- * https://ionicframework.com/docs/theming/dark-mode
- */
-
-/* @import "@ionic/angular/css/palettes/dark.always.css"; */
-/* @import "@ionic/angular/css/palettes/dark.class.css"; */
-@import '@ionic/angular/css/palettes/dark.system.css';
+/*
+ * App Global CSS
+ * ----------------------------------------------------------------------------
+ * Put style rules here that you want to apply globally. These styles are for
+ * the entire app and not just one component. Additionally, this file can be
+ * used as an entry point to import other CSS/Sass files to be included in the
+ * output CSS.
+ * For more information on global stylesheets, visit the documentation:
+ * https://ionicframework.com/docs/layout/global-stylesheets
+ */
+
+/* Core CSS required for Ionic components to work properly */
+@import "@ionic/angular/css/core.css";
+
+/* Basic CSS for apps built with Ionic */
+@import "@ionic/angular/css/normalize.css";
+@import "@ionic/angular/css/structure.css";
+@import "@ionic/angular/css/typography.css";
+@import "@ionic/angular/css/display.css";
+
+/* Optional CSS utils that can be commented out */
+@import "@ionic/angular/css/padding.css";
+@import "@ionic/angular/css/float-elements.css";
+@import "@ionic/angular/css/text-alignment.css";
+@import "@ionic/angular/css/text-transformation.css";
+@import "@ionic/angular/css/flex-utils.css";
+
+/**
+ * Ionic Dark Mode
+ * -----------------------------------------------------
+ * For more info, please see:
+ * https://ionicframework.com/docs/theming/dark-mode
+ */
+
+/* @import "@ionic/angular/css/palettes/dark.always.css"; */
+/* @import "@ionic/angular/css/palettes/dark.class.css"; */
+@import '@ionic/angular/css/palettes/dark.system.css';

+ 26 - 26
dream-app/src/index.html

@@ -1,26 +1,26 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-  <meta charset="utf-8" />
-  <title>Ionic App</title>
-
-  <base href="/" />
-
-  <meta name="color-scheme" content="light dark" />
-  <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-  <meta name="format-detection" content="telephone=no" />
-  <meta name="msapplication-tap-highlight" content="no" />
-
-  <link rel="icon" type="image/png" href="assets/icon/favicon.png" />
-
-  <!-- add to homescreen for ios -->
-  <meta name="apple-mobile-web-app-capable" content="yes" />
-  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
-</head>
-
-<body>
-  <app-root></app-root>
-</body>
-
-</html>
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8" />
+  <title>Ionic App</title>
+
+  <base href="/" />
+
+  <meta name="color-scheme" content="light dark" />
+  <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+  <meta name="format-detection" content="telephone=no" />
+  <meta name="msapplication-tap-highlight" content="no" />
+
+  <link rel="icon" type="image/png" href="assets/icon/favicon.png" />
+
+  <!-- add to homescreen for ios -->
+  <meta name="apple-mobile-web-app-capable" content="yes" />
+  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+</head>
+
+<body>
+  <app-root></app-root>
+</body>
+
+</html>

+ 14 - 14
dream-app/src/main.ts

@@ -1,14 +1,14 @@
-import { bootstrapApplication } from '@angular/platform-browser';
-import { RouteReuseStrategy, provideRouter, withPreloading, PreloadAllModules } from '@angular/router';
-import { IonicRouteStrategy, provideIonicAngular } from '@ionic/angular/standalone';
-
-import { routes } from './app/app.routes';
-import { AppComponent } from './app/app.component';
-
-bootstrapApplication(AppComponent, {
-  providers: [
-    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
-    provideIonicAngular(),
-    provideRouter(routes, withPreloading(PreloadAllModules)),
-  ],
-});
+import { bootstrapApplication } from '@angular/platform-browser';
+import { RouteReuseStrategy, provideRouter, withPreloading, PreloadAllModules } from '@angular/router';
+import { IonicRouteStrategy, provideIonicAngular } from '@ionic/angular/standalone';
+
+import { routes } from './app/app.routes';
+import { AppComponent } from './app/app.component';
+
+bootstrapApplication(AppComponent, {
+  providers: [
+    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
+    provideIonicAngular(),
+    provideRouter(routes, withPreloading(PreloadAllModules)),
+  ],
+});

+ 55 - 55
dream-app/src/polyfills.ts

@@ -1,55 +1,55 @@
-/**
- * This file includes polyfills needed by Angular and is loaded before the app.
- * You can add your own extra polyfills to this file.
- *
- * This file is divided into 2 sections:
- *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
- *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
- *      file.
- *
- * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
- * automatically update themselves. This includes recent versions of Safari, Chrome (including
- * Opera), Edge on the desktop, and iOS and Chrome on mobile.
- *
- * Learn more in https://angular.io/guide/browser-support
- */
-
-/***************************************************************************************************
- * BROWSER POLYFILLS
- */
-
-/**
- * By default, zone.js will patch all possible macroTask and DomEvents
- * user can disable parts of macroTask/DomEvents patch by setting following flags
- * because those flags need to be set before `zone.js` being loaded, and webpack
- * will put import in the top of bundle, so user need to create a separate file
- * in this directory (for example: zone-flags.ts), and put the following flags
- * into that file, and then add the following code before importing zone.js.
- * import './zone-flags';
- *
- * The flags allowed in zone-flags.ts are listed here.
- *
- * The following flags will work for all browsers.
- *
- * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
- * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
- * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
- *
- *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
- *  with the following flag, it will bypass `zone.js` patch for IE/Edge
- *
- *  (window as any).__Zone_enable_cross_context_check = true;
- *
- */
-
-import './zone-flags';
-
-/***************************************************************************************************
- * Zone JS is required by default for Angular itself.
- */
-import 'zone.js';  // Included with Angular CLI.
-
-
-/***************************************************************************************************
- * APPLICATION IMPORTS
- */
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ *      file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes recent versions of Safari, Chrome (including
+ * Opera), Edge on the desktop, and iOS and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/guide/browser-support
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/**
+ * By default, zone.js will patch all possible macroTask and DomEvents
+ * user can disable parts of macroTask/DomEvents patch by setting following flags
+ * because those flags need to be set before `zone.js` being loaded, and webpack
+ * will put import in the top of bundle, so user need to create a separate file
+ * in this directory (for example: zone-flags.ts), and put the following flags
+ * into that file, and then add the following code before importing zone.js.
+ * import './zone-flags';
+ *
+ * The flags allowed in zone-flags.ts are listed here.
+ *
+ * The following flags will work for all browsers.
+ *
+ * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
+ * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
+ * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
+ *
+ *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
+ *  with the following flag, it will bypass `zone.js` patch for IE/Edge
+ *
+ *  (window as any).__Zone_enable_cross_context_check = true;
+ *
+ */
+
+import './zone-flags';
+
+/***************************************************************************************************
+ * Zone JS is required by default for Angular itself.
+ */
+import 'zone.js';  // Included with Angular CLI.
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */

+ 14 - 14
dream-app/src/test.ts

@@ -1,14 +1,14 @@
-// This file is required by karma.conf.js and loads recursively all the .spec and framework files
-
-import 'zone.js/testing';
-import { getTestBed } from '@angular/core/testing';
-import {
-  BrowserDynamicTestingModule,
-  platformBrowserDynamicTesting
-} from '@angular/platform-browser-dynamic/testing';
-
-// First, initialize the Angular testing environment.
-getTestBed().initTestEnvironment(
-  BrowserDynamicTestingModule,
-  platformBrowserDynamicTesting(),
-);
+// This file is required by karma.conf.js and loads recursively all the .spec and framework files
+
+import 'zone.js/testing';
+import { getTestBed } from '@angular/core/testing';
+import {
+  BrowserDynamicTestingModule,
+  platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+// First, initialize the Angular testing environment.
+getTestBed().initTestEnvironment(
+  BrowserDynamicTestingModule,
+  platformBrowserDynamicTesting(),
+);

+ 2 - 2
dream-app/src/theme/variables.scss

@@ -1,2 +1,2 @@
-// For information on how to create your own theme, please see:
-// http://ionicframework.com/docs/theming/
+// For information on how to create your own theme, please see:
+// http://ionicframework.com/docs/theming/

+ 6 - 6
dream-app/src/zone-flags.ts

@@ -1,6 +1,6 @@
-/**
- * Prevents Angular change detection from
- * running with certain Web Component callbacks
- */
-// eslint-disable-next-line no-underscore-dangle
-(window as any).__Zone_disable_customElements = true;
+/**
+ * Prevents Angular change detection from
+ * running with certain Web Component callbacks
+ */
+// eslint-disable-next-line no-underscore-dangle
+(window as any).__Zone_disable_customElements = true;

+ 15 - 15
dream-app/tsconfig.app.json

@@ -1,15 +1,15 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/app",
-    "types": []
-  },
-  "files": [
-    "src/main.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.d.ts"
-  ]
-}
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "./out-tsc/app",
+    "types": []
+  },
+  "files": [
+    "src/main.ts",
+    "src/polyfills.ts"
+  ],
+  "include": [
+    "src/**/*.d.ts"
+  ]
+}

+ 30 - 30
dream-app/tsconfig.json

@@ -1,30 +1,30 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
-{
-  "compileOnSave": false,
-  "compilerOptions": {
-    "baseUrl": "./",
-    "outDir": "./dist/out-tsc",
-    "forceConsistentCasingInFileNames": true,
-    "strict": true,
-    "noImplicitOverride": true,
-    "noPropertyAccessFromIndexSignature": true,
-    "noImplicitReturns": true,
-    "noFallthroughCasesInSwitch": true,
-    "sourceMap": true,
-    "declaration": false,
-    "downlevelIteration": true,
-    "experimentalDecorators": true,
-    "moduleResolution": "node",
-    "importHelpers": true,
-    "target": "es2022",
-    "module": "es2020",
-    "lib": ["es2018", "dom"],
-    "useDefineForClassFields": false
-  },
-  "angularCompilerOptions": {
-    "enableI18nLegacyMessageIdFormat": false,
-    "strictInjectionParameters": true,
-    "strictInputAccessModifiers": true,
-    "strictTemplates": true
-  }
-}
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
+{
+  "compileOnSave": false,
+  "compilerOptions": {
+    "baseUrl": "./",
+    "outDir": "./dist/out-tsc",
+    "forceConsistentCasingInFileNames": true,
+    "strict": true,
+    "noImplicitOverride": true,
+    "noPropertyAccessFromIndexSignature": true,
+    "noImplicitReturns": true,
+    "noFallthroughCasesInSwitch": true,
+    "sourceMap": true,
+    "declaration": false,
+    "downlevelIteration": true,
+    "experimentalDecorators": true,
+    "moduleResolution": "node",
+    "importHelpers": true,
+    "target": "es2022",
+    "module": "es2020",
+    "lib": ["es2018", "dom"],
+    "useDefineForClassFields": false
+  },
+  "angularCompilerOptions": {
+    "enableI18nLegacyMessageIdFormat": false,
+    "strictInjectionParameters": true,
+    "strictInputAccessModifiers": true,
+    "strictTemplates": true
+  }
+}

+ 18 - 18
dream-app/tsconfig.spec.json

@@ -1,18 +1,18 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/spec",
-    "types": [
-      "jasmine"
-    ]
-  },
-  "files": [
-    "src/test.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.spec.ts",
-    "src/**/*.d.ts"
-  ]
-}
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "./out-tsc/spec",
+    "types": [
+      "jasmine"
+    ]
+  },
+  "files": [
+    "src/test.ts",
+    "src/polyfills.ts"
+  ],
+  "include": [
+    "src/**/*.spec.ts",
+    "src/**/*.d.ts"
+  ]
+}

+ 143 - 143
dream-prod/README.md

@@ -1,143 +1,143 @@
-# 《好梦》项目策划书
-
--姓名 聂翼伏
--学号 202226701006
--班级 22大数据班
--手机 17779133711
-
-一句话描述:
-《好梦》是一款专注于睡眠质量反馈的应用,面向关注自身睡眠健康的用户,通过分析手机或智能穿戴设备在睡眠期间收集的数据(如间隔录音、心率等),帮助用户了解自身睡眠状况,并提供新一天的状态评估和改善建议。
-
-# 一、项目设想
-	1.  一句话描述项目设想:
-《好梦》是一款专注于睡眠质量反馈的应用,面向关注自身睡眠健康的用户,通过分析手机或智能穿戴设备在睡眠期间收集的数据(如间隔录音、心率等),帮助用户了解自身睡眠状况,并提供新一天的状态评估和改善建议。
-
-	2.	项目的业务流程
-		数据采集:通过手机或智能穿戴设备,实时收集用户在睡眠期间的心率、呼吸频率、体动、环境噪音等数据。
-		数据分析:利用先进的算法,对采集的数据进行处理,生成详细的睡眠报告,包括睡眠时长、深浅睡眠比例、夜间觉醒次数等指标。
-		反馈与建议:根据分析结果,向用户提供个性化的睡眠质量反馈,并提出改善建议,如调整作息时间、优化睡眠环境等。
-		状态评估:结合睡眠数据,评估用户新一天的精神状态,提醒用户注意事项,帮助其更好地规划日常活动。
-		长期监测与调整:持续监测用户的睡眠模式,提供趋势分析,帮助用户长期改善睡眠质量。
-
-	3.	项目的商业模式
-	•	基础功能免费:提供基本的睡眠监测和报告功能,吸引用户使用。
-	•	高级订阅服务:提供深度数据分析、个性化建议、专家咨询等增值服务,用户可按月或按年订阅。
-	•	硬件销售:与智能穿戴设备厂商合作,销售与应用配套的硬件设备,获取销售分成。
-	•	数据服务:在确保用户隐私的前提下,向科研机构、医疗机构提供匿名的睡眠数据,获取数据服务收入。
-
-	4.	相对可行的策略
-	•	初期策略:
-	•	    市场调研:深入了解目标用户的需求和痛点,优化产品功能。
-	•	    产品开发:快速迭代,推出MVP(最小可行产品),验证市场反应。
-	•	    用户获取:通过社交媒体、健康社区等渠道进行推广,吸引早期用户。
-	•	中期策略:
-	•	    功能完善:根据用户反馈,持续优化产品功能,提升用户体验。
-	•	    合作拓展:与医疗机构、睡眠研究中心合作,提升产品专业性和可信度。
-	•	    品牌建设:通过内容营销、用户案例分享等方式,建立品牌形象,增强用户信任。
-	•	长期策略:
-	•	    技术创新:引入人工智能和大数据分析技术,提升数据分析的准确性和深度。
-	•	    国际拓展:在国内市场稳定后,逐步拓展至国际市场,满足全球用户需求。
-	•	    生态构建:打造睡眠健康生态圈,整合相关产品和服务,提供一站式解决方案。
-
-# 二、项目背景
-	1.	政策背景
-        近年来,国家高度重视国民健康,出台多项政策鼓励健康产业的发展。 例如,《“健康中国2030”规划纲要》提出,要提高全民健康水平,强调睡眠健康作为重要组成部分。 此外,国家鼓励发展数字健康服务,为“好梦”项目提供了良好的政策环境。
-![alt text](image/image.png)
-        
-	2.	行业背景
-        随着生活节奏加快和工作压力增加,睡眠问题日益突出。 根据中国睡眠研究会的数据,超过60%的中国人存在不同程度的睡眠问题。 市场上已有多款睡眠监测应用,但大多功能单一,缺乏个性化反馈,用户满意度较低。
-![alt text](image/image-1.png)
-	3.	市场痛点
-	•	数据准确性不足:现有应用多依赖手机传感器,数据采集精度有限,影响分析结果的准确性。
-	•	反馈不够个性化:大多数应用提供的反馈泛泛而谈,缺乏针对性,用户难以从中获益。
-	•	缺乏长期监测:许多应用仅提供单次睡眠报告,无法帮助用户了解长期睡眠趋势,难以指导持续改善。
-![alt text](image/image-2.png)
-
-# 三、产品定位
-	1.  用户分析
-
-	•	目标用户:
-	•	大学生:学习压力大,作息不规律,关注自身健康。
-	•	上班族:工作压力大,睡眠质量差,寻求改善方法。
-	•	中老年人:关注健康,渴望了解自身睡眠状况。
-
-	2.	主要功能
-
-	- 记录梦境:随时打开记录自己的梦境,形成梦境卡片。
-	- 梦境分析:运用AIGC文本生成,根据用户所描述的梦境以及自身的情感体验,来解梦,同时给出建议,引导其积极情绪。
-	- 梦境描绘:运用AIGC图片生成,根据用户描述的梦境场景、元素、风格,生成梦境的印象图片
-
-	•	睡眠监测:通过设备采集数据,实时监测用户睡眠状况。
-	•	智能分析:利用AGI技术,处理多种类型的数据,如音频、心率、运动等。通过融合这些数据,AGI可以更准确
-        地识别用户的睡眠阶段、检测异常事件(如睡眠呼吸暂停)等,从而提供更全面的睡眠分析,也可以根据用户的历史睡眠数据和当前状态,提供个性化的睡眠改善建议,如调整作息时间、优化睡眠环境等,帮助用户提升睡眠质量。
-        智能睡眠分析系统时序图:
-
-```plantuml
-    @startuml
-    actor 用户 as user
-    entity "智能睡眠分析系统" as system
-
-    user -> system: 请求睡眠报告
-    activate system
-    system -> system: 处理睡眠数据
-    system -> user: 显示睡眠质量报告
-    deactivate system
-    @enduml
-```
-
-	•	报告生成:生成详细的睡眠报告,包括睡眠得分、睡眠阶段、建议等。
-	•	个性化建议:根据分析结果,提供针对性的睡眠改善建议。
-	•	趋势分析:长期跟踪用户睡眠数据,分析趋势,提供深度洞察。
-
-    
-# 四、可行性测试
-    1.	数据采集的可行性
-
-	•	设备普及:智能手机和穿戴设备的普及,为数据采集提供了硬件基础。
-	•	技术成熟:现有技术能够准确采集心率、体动等睡眠相关数据。
-
-	2.	数据分析的可行性
-
-	•	AGI技术发展:人工智能技术的发展,使得对睡眠数据的深度分析成为可能。
-	•	算法优化:通过不断优化算法,提高分析的准确性和可靠性。
-
-# 五、产品结构
-    1、竞品分析
-	a.Pillow
-	•	核心功能:
-	•	自动或手动睡眠跟踪。
-	•	睡眠阶段分析(浅睡、深睡、REM)。
-	•	智能闹钟,在最佳睡眠阶段唤醒用户。
-	•	记录和分析打鼾、睡眠谈话等声音。
-	•	与 Apple Health 数据同步。
-	•	优点:
-	•	界面友好,易于使用。
-	•	提供详细的睡眠分析报告。
-	•	支持多种睡眠模式(午睡、整夜睡眠)。
-	•	缺点:
-	•	部分高级功能需付费解锁。
-	•	对于不使用 Apple Watch 的用户,功能可能受限。
-![alt text](image/image-3.png)
-
-	b.	AutoSleep
-	•	核心功能:
-	•	自动睡眠检测,无需手动启动。
-	•	提供睡眠质量评分。
-	•	心率监测与分析。
-	•	与 Apple Health 深度集成。
-	•	优点:
-	•	自动化程度高,用户干预少。
-	•	提供多维度的睡眠数据分析。
-	•	定期更新,持续改进功能。
-	•	缺点:
-	•	界面相对复杂,新用户可能需要时间适应。
-	•	部分功能需要付费解锁。
-![alt text](image/image-4.png)
-
-    2、产品结构图
-![alt text](image/image-5.png)
-
-    3、产品信息图
-![alt text](image/image-6.png)
-
-
+# 《好梦》项目策划书
+
+-姓名 聂翼伏
+-学号 202226701006
+-班级 22大数据班
+-手机 17779133711
+
+一句话描述:
+《好梦》是一款专注于睡眠质量反馈的应用,面向关注自身睡眠健康的用户,通过分析手机或智能穿戴设备在睡眠期间收集的数据(如间隔录音、心率等),帮助用户了解自身睡眠状况,并提供新一天的状态评估和改善建议。
+
+# 一、项目设想
+	1.  一句话描述项目设想:
+《好梦》是一款专注于睡眠质量反馈的应用,面向关注自身睡眠健康的用户,通过分析手机或智能穿戴设备在睡眠期间收集的数据(如间隔录音、心率等),帮助用户了解自身睡眠状况,并提供新一天的状态评估和改善建议。
+
+	2.	项目的业务流程
+		数据采集:通过手机或智能穿戴设备,实时收集用户在睡眠期间的心率、呼吸频率、体动、环境噪音等数据。
+		数据分析:利用先进的算法,对采集的数据进行处理,生成详细的睡眠报告,包括睡眠时长、深浅睡眠比例、夜间觉醒次数等指标。
+		反馈与建议:根据分析结果,向用户提供个性化的睡眠质量反馈,并提出改善建议,如调整作息时间、优化睡眠环境等。
+		状态评估:结合睡眠数据,评估用户新一天的精神状态,提醒用户注意事项,帮助其更好地规划日常活动。
+		长期监测与调整:持续监测用户的睡眠模式,提供趋势分析,帮助用户长期改善睡眠质量。
+
+	3.	项目的商业模式
+	•	基础功能免费:提供基本的睡眠监测和报告功能,吸引用户使用。
+	•	高级订阅服务:提供深度数据分析、个性化建议、专家咨询等增值服务,用户可按月或按年订阅。
+	•	硬件销售:与智能穿戴设备厂商合作,销售与应用配套的硬件设备,获取销售分成。
+	•	数据服务:在确保用户隐私的前提下,向科研机构、医疗机构提供匿名的睡眠数据,获取数据服务收入。
+
+	4.	相对可行的策略
+	•	初期策略:
+	•	    市场调研:深入了解目标用户的需求和痛点,优化产品功能。
+	•	    产品开发:快速迭代,推出MVP(最小可行产品),验证市场反应。
+	•	    用户获取:通过社交媒体、健康社区等渠道进行推广,吸引早期用户。
+	•	中期策略:
+	•	    功能完善:根据用户反馈,持续优化产品功能,提升用户体验。
+	•	    合作拓展:与医疗机构、睡眠研究中心合作,提升产品专业性和可信度。
+	•	    品牌建设:通过内容营销、用户案例分享等方式,建立品牌形象,增强用户信任。
+	•	长期策略:
+	•	    技术创新:引入人工智能和大数据分析技术,提升数据分析的准确性和深度。
+	•	    国际拓展:在国内市场稳定后,逐步拓展至国际市场,满足全球用户需求。
+	•	    生态构建:打造睡眠健康生态圈,整合相关产品和服务,提供一站式解决方案。
+
+# 二、项目背景
+	1.	政策背景
+        近年来,国家高度重视国民健康,出台多项政策鼓励健康产业的发展。 例如,《“健康中国2030”规划纲要》提出,要提高全民健康水平,强调睡眠健康作为重要组成部分。 此外,国家鼓励发展数字健康服务,为“好梦”项目提供了良好的政策环境。
+![alt text](image/image.png)
+        
+	2.	行业背景
+        随着生活节奏加快和工作压力增加,睡眠问题日益突出。 根据中国睡眠研究会的数据,超过60%的中国人存在不同程度的睡眠问题。 市场上已有多款睡眠监测应用,但大多功能单一,缺乏个性化反馈,用户满意度较低。
+![alt text](image/image-1.png)
+	3.	市场痛点
+	•	数据准确性不足:现有应用多依赖手机传感器,数据采集精度有限,影响分析结果的准确性。
+	•	反馈不够个性化:大多数应用提供的反馈泛泛而谈,缺乏针对性,用户难以从中获益。
+	•	缺乏长期监测:许多应用仅提供单次睡眠报告,无法帮助用户了解长期睡眠趋势,难以指导持续改善。
+![alt text](image/image-2.png)
+
+# 三、产品定位
+	1.  用户分析
+
+	•	目标用户:
+	•	大学生:学习压力大,作息不规律,关注自身健康。
+	•	上班族:工作压力大,睡眠质量差,寻求改善方法。
+	•	中老年人:关注健康,渴望了解自身睡眠状况。
+
+	2.	主要功能
+
+	- 记录梦境:随时打开记录自己的梦境,形成梦境卡片。
+	- 梦境分析:运用AIGC文本生成,根据用户所描述的梦境以及自身的情感体验,来解梦,同时给出建议,引导其积极情绪。
+	- 梦境描绘:运用AIGC图片生成,根据用户描述的梦境场景、元素、风格,生成梦境的印象图片
+
+	•	睡眠监测:通过设备采集数据,实时监测用户睡眠状况。
+	•	智能分析:利用AGI技术,处理多种类型的数据,如音频、心率、运动等。通过融合这些数据,AGI可以更准确
+        地识别用户的睡眠阶段、检测异常事件(如睡眠呼吸暂停)等,从而提供更全面的睡眠分析,也可以根据用户的历史睡眠数据和当前状态,提供个性化的睡眠改善建议,如调整作息时间、优化睡眠环境等,帮助用户提升睡眠质量。
+        智能睡眠分析系统时序图:
+
+```plantuml
+    @startuml
+    actor 用户 as user
+    entity "智能睡眠分析系统" as system
+
+    user -> system: 请求睡眠报告
+    activate system
+    system -> system: 处理睡眠数据
+    system -> user: 显示睡眠质量报告
+    deactivate system
+    @enduml
+```
+
+	•	报告生成:生成详细的睡眠报告,包括睡眠得分、睡眠阶段、建议等。
+	•	个性化建议:根据分析结果,提供针对性的睡眠改善建议。
+	•	趋势分析:长期跟踪用户睡眠数据,分析趋势,提供深度洞察。
+
+    
+# 四、可行性测试
+    1.	数据采集的可行性
+
+	•	设备普及:智能手机和穿戴设备的普及,为数据采集提供了硬件基础。
+	•	技术成熟:现有技术能够准确采集心率、体动等睡眠相关数据。
+
+	2.	数据分析的可行性
+
+	•	AGI技术发展:人工智能技术的发展,使得对睡眠数据的深度分析成为可能。
+	•	算法优化:通过不断优化算法,提高分析的准确性和可靠性。
+
+# 五、产品结构
+    1、竞品分析
+	a.Pillow
+	•	核心功能:
+	•	自动或手动睡眠跟踪。
+	•	睡眠阶段分析(浅睡、深睡、REM)。
+	•	智能闹钟,在最佳睡眠阶段唤醒用户。
+	•	记录和分析打鼾、睡眠谈话等声音。
+	•	与 Apple Health 数据同步。
+	•	优点:
+	•	界面友好,易于使用。
+	•	提供详细的睡眠分析报告。
+	•	支持多种睡眠模式(午睡、整夜睡眠)。
+	•	缺点:
+	•	部分高级功能需付费解锁。
+	•	对于不使用 Apple Watch 的用户,功能可能受限。
+![alt text](image/image-3.png)
+
+	b.	AutoSleep
+	•	核心功能:
+	•	自动睡眠检测,无需手动启动。
+	•	提供睡眠质量评分。
+	•	心率监测与分析。
+	•	与 Apple Health 深度集成。
+	•	优点:
+	•	自动化程度高,用户干预少。
+	•	提供多维度的睡眠数据分析。
+	•	定期更新,持续改进功能。
+	•	缺点:
+	•	界面相对复杂,新用户可能需要时间适应。
+	•	部分功能需要付费解锁。
+![alt text](image/image-4.png)
+
+    2、产品结构图
+![alt text](image/image-5.png)
+
+    3、产品信息图
+![alt text](image/image-6.png)
+
+

+ 38 - 38
dream-prod/image/产品信息图.md

@@ -1,39 +1,39 @@
-# 好梦应用产品信息图
-
-## 用户信息
-- **姓名**
-- **年龄**
-- **性别**
-- **睡眠目标**
-
-## 睡眠数据
-- **睡眠时长**
-- **睡眠阶段**
-  - 浅睡
-  - 深睡
-  - REM
-- **入睡时间**
-- **醒来时间**
-- **中途醒来次数**
-- **睡眠效率**
-
-## 心率数据
-- **平均心率**
-- **最低心率**
-- **最高心率**
-- **心率变异性**
-
-## 声音数据
-- **打鼾时长**
-- **睡眠谈话片段**
-- **环境噪音水平**
-
-## 建议与提醒
-- **个性化睡眠建议**
-  - 根据历史数据优化睡眠习惯
-  - 改善睡眠环境(如降噪、调节光线)
-- **睡前准备提醒**
-  - 提醒用户调整作息、放松心情
-- **起床后建议**
-  - 提供当天精神状态评估
+# 好梦应用产品信息图
+
+## 用户信息
+- **姓名**
+- **年龄**
+- **性别**
+- **睡眠目标**
+
+## 睡眠数据
+- **睡眠时长**
+- **睡眠阶段**
+  - 浅睡
+  - 深睡
+  - REM
+- **入睡时间**
+- **醒来时间**
+- **中途醒来次数**
+- **睡眠效率**
+
+## 心率数据
+- **平均心率**
+- **最低心率**
+- **最高心率**
+- **心率变异性**
+
+## 声音数据
+- **打鼾时长**
+- **睡眠谈话片段**
+- **环境噪音水平**
+
+## 建议与提醒
+- **个性化睡眠建议**
+  - 根据历史数据优化睡眠习惯
+  - 改善睡眠环境(如降噪、调节光线)
+- **睡前准备提醒**
+  - 提醒用户调整作息、放松心情
+- **起床后建议**
+  - 提供当天精神状态评估
   - 推荐适合的晨间活动

+ 70 - 70
dream-prod/image/产品结构图.md

@@ -1,71 +1,71 @@
-# 好梦应用产品结构图
-
-## 首页
-- **今日睡眠概览**
-  - 昨晚睡眠得分
-  - 睡眠时长
-  - 打鼾提醒
-  - 环境噪音反馈
-- **快捷入口**
-  - 历史趋势
-  - 个性化建议
-
-## 数据中心
-- **2C 用户**
-  - **睡眠数据**
-    - 浅睡时长
-    - 深睡时长
-    - REM 时长
-    - 入睡时间、醒来时间
-    - 中途醒来次数
-    - 睡眠效率
-  - **心率数据**
-    - 平均心率
-    - 最低心率
-    - 最高心率
-    - 心率变异性
-  - **声音数据**
-    - 打鼾时长
-    - 睡眠谈话片段
-    - 环境噪音水平
-- **2B 企业/机构**
-  - **数据接口**
-    - 开放API
-    - 批量导出功能
-  - **数据分析后台**
-    - 趋势分析
-    - 企业睡眠健康报告
-
-## 建议与反馈
-- **个性化建议**
-  - 最佳入睡时间
-  - 改善睡眠环境
-- **睡前准备提醒**
-  - 降低光线
-  - 降噪设备推荐
-- **起床后建议**
-  - 精神状态评估
-  - 早间活力建议
-
-## 企业合作模块
-- **企业健康管理**
-  - 团队睡眠数据统计
-  - 健康改善方案定制
-- **医疗合作服务**
-  - 睡眠报告整合
-  - 专家咨询入口
-
-## 设备管理
-- **数据同步**
-  - 智能手环/手机联动
-  - 健康App同步
-- **用户信息管理**
-  - 姓名
-  - 年龄
-  - 性别
-  - 睡眠目标
-- **数据隐私管理**
-  - 数据加密
-  - 云端备份与恢复
-- **设备绑定**
+# 好梦应用产品结构图
+
+## 首页
+- **今日睡眠概览**
+  - 昨晚睡眠得分
+  - 睡眠时长
+  - 打鼾提醒
+  - 环境噪音反馈
+- **快捷入口**
+  - 历史趋势
+  - 个性化建议
+
+## 数据中心
+- **2C 用户**
+  - **睡眠数据**
+    - 浅睡时长
+    - 深睡时长
+    - REM 时长
+    - 入睡时间、醒来时间
+    - 中途醒来次数
+    - 睡眠效率
+  - **心率数据**
+    - 平均心率
+    - 最低心率
+    - 最高心率
+    - 心率变异性
+  - **声音数据**
+    - 打鼾时长
+    - 睡眠谈话片段
+    - 环境噪音水平
+- **2B 企业/机构**
+  - **数据接口**
+    - 开放API
+    - 批量导出功能
+  - **数据分析后台**
+    - 趋势分析
+    - 企业睡眠健康报告
+
+## 建议与反馈
+- **个性化建议**
+  - 最佳入睡时间
+  - 改善睡眠环境
+- **睡前准备提醒**
+  - 降低光线
+  - 降噪设备推荐
+- **起床后建议**
+  - 精神状态评估
+  - 早间活力建议
+
+## 企业合作模块
+- **企业健康管理**
+  - 团队睡眠数据统计
+  - 健康改善方案定制
+- **医疗合作服务**
+  - 睡眠报告整合
+  - 专家咨询入口
+
+## 设备管理
+- **数据同步**
+  - 智能手环/手机联动
+  - 健康App同步
+- **用户信息管理**
+  - 姓名
+  - 年龄
+  - 性别
+  - 睡眠目标
+- **数据隐私管理**
+  - 数据加密
+  - 云端备份与恢复
+- **设备绑定**
   - 添加/解绑智能设备