焦怡璇 1 năm trước cách đây
mục cha
commit
7eb8bc364c
27 tập tin đã thay đổi với 2654 bổ sung39 xóa
  1. 1 0
      .vscode/settings.json
  2. 145 3
      README.md
  3. 4 4
      heartvoice-app/package-lock.json
  4. 1 1
      heartvoice-app/package.json
  5. 25 0
      heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.html
  6. 15 0
      heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.scss
  7. 22 0
      heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.spec.ts
  8. 62 0
      heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.ts
  9. 1 1
      heartvoice-app/src/app/interlocution/interlocution.component.ts
  10. 19 0
      heartvoice-app/src/app/personality-test/personality-test.component.html
  11. 0 0
      heartvoice-app/src/app/personality-test/personality-test.component.scss
  12. 22 0
      heartvoice-app/src/app/personality-test/personality-test.component.spec.ts
  13. 68 0
      heartvoice-app/src/app/personality-test/personality-test.component.ts
  14. 3 4
      heartvoice-app/src/app/tab1/tab1.page.html
  15. 12 1
      heartvoice-app/src/app/tab1/tab1.page.scss
  16. 8 1
      heartvoice-app/src/app/tab1/tab1.page.ts
  17. 1 4
      heartvoice-app/src/app/tab2/tab2.page.html
  18. 13 4
      heartvoice-app/src/app/tab2/tab2.page.scss
  19. 28 12
      heartvoice-app/src/app/tab3/tab3.page.html
  20. 53 0
      heartvoice-app/src/app/tab3/tab3.page.scss
  21. 1 0
      heartvoice-app/src/app/tab3/tab3.page.spec.ts
  22. 24 4
      heartvoice-app/src/app/tab3/tab3.page.ts
  23. 10 0
      heartvoice-app/src/app/tabs/tabs.routes.ts
  24. 194 0
      heartvoice-app/src/lib/ncloud.ts
  25. 163 0
      heartvoice-server/lib/ncloud.js
  26. 1482 0
      heartvoice-server/migration/data.js
  27. 277 0
      heartvoice-server/migration/import-data.js

+ 1 - 0
.vscode/settings.json

@@ -1,5 +1,6 @@
 {
     "plantuml.server": "http://192.168.1.100:8080",
     "plantuml.render": "PlantUMLServer",
+    "liveServer.settings.port": 5501,
 
 }

+ 145 - 3
README.md

@@ -1,4 +1,146 @@
-# 心语项目仓库
+表结构
+heartvoiceuser(用户表)
+objectId (唯一标识)
+createdAt (创建时间)
+username (用户名)
+password (密码)
+email (邮箱地址)
+phoneNumber (手机号)
 
-- heartVoice-app 前端代码
-- heartVoice-prod 产品文档
+Questions(问题表)
+objectId (唯一标识)
+createdAt (创建时间)
+questionText (问题文本)
+dimension (维度,例如 E/I, S/N, T/F, J/P):string
+
+option(选项表)
+objectId (唯一标识)
+createdAt (创建时间)
+question (Pointer) (关联的题目)
+optionText (选项文本)
+weight (权重,取值为 1, 0.5, 0, -0.5, -1):string
+
+UserResponse(用户回答表)
+objectId (唯一标识)
+createdAt (创建时间)
+user (Pointer) (关联的用户)
+question (Pointer) (关联的题目)
+selectedOption (Pointer) (用户选择的选项)
+weight (权重,取值为 1, 0.5, 0, -0.5, -1)
+
+Chat(聊天记录表)
+objectId (唯一标识)
+createdAt (创建时间)
+user (Pointer) (关联的用户)
+chatContent (聊天内容)
+chatTime (聊天时间)
+emotion (情绪状态)
+
+PersonalityReport(个性化心理报告表)
+objectId (唯一标识)
+createdAt (创建时间)
+user (Pointer) (关联的用户)
+mbtiType (用户的MBTI类型)
+reportContent (报告内容)
+suggestions (建议)
+
+Feedback(用户反馈表)
+objectId (唯一标识)
+createdAt (创建时间)
+user (Pointer) (关联的用户)
+feedbackContent (反馈内容)
+
+
+
+class User {
+    +objectId: String
+    +createdAt: Date
+    +username: String
+    +password: String
+    +email: String
+    +phoneNumber: String
+}
+
+class Question {
+    +objectId: String
+    +createdAt: Date
+    +questionText: String
+    +dimension: String
+}
+
+class Option {
+    +objectId: String
+    +createdAt: Date
+    +optionText: String
+    +weight: String
+    +question: Pointer
+}
+
+class UserResponse {
+    +objectId: String
+    +createdAt: Date
+    +user: Pointer
+    +question: Pointer
+    +selectedOption: Pointer
+    +weight: String } 
+    class Chat { 
+        +objectId: String 
+        +createdAt: Date 
+        +user: Pointer 
+        +chatContent: String 
+        +chatTime: Date 
+        +emotion: String } 
+        class PersonalityReport { 
+            +objectId: String 
+            +createdAt: Date 
+            +user: Pointer 
+            +mbtiType: String 
+            +reportContent: String 
+            +suggestions: String } 
+            class Feedback 
+            { +objectId: String 
+        +createdAt: Date 
+        +user: Pointer 
+        +feedbackContent: String } 
+        User "1" -- "0..*" UserResponse : answered 
+        User "1" -- "0..*" Chat : has 
+        User "1" -- "0..*" PersonalityReport : generates 
+        User "1" -- "0..*" Feedback : gives 
+        Question "1" -- "0..*" Option : has 
+        Question "1" -- "0..*" UserResponse : answered by @enduml
+
+
+
+
+
+        async function importObject(className, data) {
+  // 查重 srcId 数据源列表中的objectId并非数据库生成的唯一ID,因此需要有一个srcId字段进行记录,并查重
+  let query = new CloudQuery(className);
+  let srcId = data.objectId;
+  query.equalTo("srcId", srcId);
+  let importObj = await query.first();
+  console.log(importObj);
+
+  // 导入前批量处理Pointer类型数据,进行重定向
+  Object.keys(data)?.forEach(key => {
+      let field = data[key];
+      let srcId = field?.objectId;
+      if (srcId) { // 是数组字段
+          if (key == "question") { // 处理指向问题的指针
+              data[key] = DataMap?.["Questions"]?.[srcId]?.toPointer(); // 确保指向 Questions
+          }
+      }
+  });
+
+  // 若未添加,则创建新对象并保存
+  if (!importObj?.id) {
+      importObj = new CloudObject(className);
+  }
+
+  // 保存或更新数据
+  data.srcId = srcId;
+  importObj.set(data);
+  importObj = await importObj.save();
+
+  DataMap[className][srcId] = importObj;
+}

+ 4 - 4
heartvoice-app/package-lock.json

@@ -17,7 +17,7 @@
         "@angular/platform-browser-dynamic": "^18.0.0",
         "@angular/router": "^18.0.0",
         "@ionic/angular": "^8.0.0",
-        "fmode-ng": "^0.0.62",
+        "fmode-ng": "^0.0.63",
         "ionicons": "^7.2.1",
         "rxjs": "~7.8.0",
         "tslib": "^2.3.0",
@@ -9585,9 +9585,9 @@
       "license": "ISC"
     },
     "node_modules/fmode-ng": {
-      "version": "0.0.62",
-      "resolved": "https://registry.npmmirror.com/fmode-ng/-/fmode-ng-0.0.62.tgz",
-      "integrity": "sha512-F0RzEu47NgKpaHp/vBEzjsU4efJ1lKLAbbdPE5hltj1W1cDaeht/i6UlEidid4FAEdAg7c9rrQrLgOh/zUfCsg==",
+      "version": "0.0.63",
+      "resolved": "https://registry.npmmirror.com/fmode-ng/-/fmode-ng-0.0.63.tgz",
+      "integrity": "sha512-gTiDZO2CchcTYAmlaweapasqV/8PdhG2vizJNn5dYZyXjgtrjyW+KeW5k2EVyIDvM1+bMGjjhGmr76Fc0TElxw==",
       "license": "COPYRIGHT © 未来飞马 未来全栈 www.fmode.cn All RIGHTS RESERVED",
       "dependencies": {
         "tslib": "^2.3.0"

+ 1 - 1
heartvoice-app/package.json

@@ -22,7 +22,7 @@
     "@angular/platform-browser-dynamic": "^18.0.0",
     "@angular/router": "^18.0.0",
     "@ionic/angular": "^8.0.0",
-    "fmode-ng": "^0.0.62",
+    "fmode-ng": "^0.0.63",
     "ionicons": "^7.2.1",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",

+ 25 - 0
heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.html

@@ -0,0 +1,25 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-title>心理支持聊天</ion-title>
+    <ion-buttons slot="start">
+      <ion-button routerLink="/my-page">返回</ion-button>
+    </ion-buttons>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <!-- 聊天记录区域 -->
+  <ion-list>
+    <ion-item *ngFor="let message of messages" [ngClass]="{'user-message': message.sender === 'user', 'ai-message': message.sender === 'ai'}">
+      <ion-label>{{ message.content }}</ion-label>
+    </ion-item>
+  </ion-list>
+
+  <!-- 用户输入框 -->
+  <ion-footer>
+    <ion-toolbar>
+      <ion-input placeholder="输入你的消息..." [(ngModel)]="userInput"></ion-input>
+      <ion-button (click)="sendUserMessage()" color="primary">发送</ion-button>
+    </ion-toolbar>
+  </ion-footer>
+</ion-content>

+ 15 - 0
heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.scss

@@ -0,0 +1,15 @@
+.user-message {
+    background-color: #d1e7dd; /* 用户消息背景色 */
+    text-align: right; /* 用户消息右对齐 */
+    padding: 10px;
+    border-radius: 10px;
+    margin: 5px 0;
+  }
+  
+  .ai-message {
+    background-color: #f8d7da; /* AI消息背景色 */
+    text-align: left; /* AI消息左对齐 */
+    padding: 10px;
+    border-radius: 10px;
+    margin: 5px 0;
+  }

+ 22 - 0
heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.spec.ts

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

+ 62 - 0
heartvoice-app/src/app/gexinhualiaotian/gexinhualiaotian.component.ts

@@ -0,0 +1,62 @@
+import { Component, OnInit } from '@angular/core';
+import { IonButton, IonButtons, IonContent, IonFooter, IonHeader, IonInput, IonItem, IonLabel, IonList, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { FmodeChatCompletion } from 'fmode-ng';
+import { FormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common'; // 导入 CommonModule
+
+@Component({
+  selector: 'app-home',
+  standalone: true,
+  templateUrl: './gexinhualiaotian.component.html',
+  styleUrls: ['./gexinhualiaotian.component.scss'],
+  imports: [
+    IonContent, IonButton, IonInput, IonList, IonHeader, IonToolbar, IonTitle, IonButtons, 
+    CommonModule, IonFooter, IonLabel, IonItem, FormsModule
+  ],
+})
+export class GexinhualiaotianComponent implements OnInit {
+  userInput: string = ''; // 用户输入的消息
+  messages: { content: string; sender: string }[] = []; // 消息数组
+  isSending: boolean = false; // 标记是否正在发送消息
+
+  constructor() {}
+
+  ngOnInit() {}
+
+  // 发送用户输入的消息
+  sendUserMessage() {
+    if (this.userInput.trim() && !this.isSending) {
+      // 将用户输入添加到消息数组
+      this.messages.push({ content: this.userInput, sender: 'user' });
+      this.sendMessage(); // 发送消息后调用 sendMessage 方法
+    }
+  }
+
+  // 方法:实例化completion对象,传入消息数组,并订阅生成的可观察对象
+  sendMessage() {
+    console.log("create");
+    this.isSending = true; // 设置为正在发送状态
+
+    let completion = new FmodeChatCompletion([
+      { role: "system", content: "你是一名心理医生,请根据用户的输入进行聊天。" },
+      { role: "user", content: this.userInput }
+    ]);
+
+    completion.sendCompletion().subscribe((message: any) => {
+      // 打印消息体
+      console.log(message.content);
+      // 赋值消息内容给组件内属性
+      const responseMsg = message.content;
+
+      // 将AI回复添加到消息数组
+      // 等待AI回复完全生成后再添加
+      setTimeout(() => {
+        this.messages.push({ content: responseMsg, sender: 'ai' });
+        this.isSending = false; // 发送完成,重置状态
+      }, 1000); // 模拟生成延迟,您可以根据实际情况调整时间
+
+      // 清空用户输入
+      this.userInput = '';
+    });
+  }
+}

+ 1 - 1
heartvoice-app/src/app/interlocution/interlocution.component.ts

@@ -32,7 +32,7 @@ export class InterlocutionComponent  implements OnInit {
     console.log("create")
 
     let PromptTemplate =`
-    你作为一名专业的心理医生,用户心情是${this.happy},请你根据用户说的话,与用户聊天,并尽量安抚他。
+    你作为一名专业的心理医生,用户心情是${this.happy},请你根据用户说的话,推测用户的性格,与用户聊天,并尽量安抚他。
     以下是用户的口述:${this.userPrompt}
      `
 

+ 19 - 0
heartvoice-app/src/app/personality-test/personality-test.component.html

@@ -0,0 +1,19 @@
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>mbti</ion-card-title>
+    <ion-card-subtitle>请回答以下问题</ion-card-subtitle>
+  </ion-card-header>
+  <ion-card-content>
+    <ion-list>
+      <ion-item *ngFor="let question of questionsList">
+        <h3>{{ question.get('questionText') }}</h3>
+        <ion-list>
+          <ion-item *ngFor="let option of getOptionsForQuestion(question.objectId)">
+            <div class="option-info">
+              <p>{{ option.get('optionText') }}</p>
+            </div>
+          </ion-item>
+        </ion-list>
+      </ion-item>
+    </ion-list>
+  </ion-card-content>

+ 0 - 0
heartvoice-app/src/app/personality-test/personality-test.component.scss


+ 22 - 0
heartvoice-app/src/app/personality-test/personality-test.component.spec.ts

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

+ 68 - 0
heartvoice-app/src/app/personality-test/personality-test.component.ts

@@ -0,0 +1,68 @@
+
+import { Component, OnInit } from '@angular/core';
+import { IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonItem, IonList } from '@ionic/angular/standalone';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
+
+@Component({
+  selector: 'app-personality-test',
+  templateUrl: './personality-test.component.html',
+  styleUrls: ['./personality-test.component.scss'],
+  standalone: true,
+  imports: [IonCard,IonCardHeader,IonCardSubtitle,IonCardTitle,IonCardContent,IonList,IonItem],
+})
+export class PersonalityTestComponent  implements OnInit {
+
+  constructor() { }
+
+
+  ngOnInit() {
+    // 生命周期:页面加载后,运行列表加载函数
+  // 创建用于数据列表存储的属性
+
+    this.loadQuestionsList()
+  }
+
+ 
+  questionsList: Array<CloudObject> = [];
+  optionList: Array<CloudObject> = [];
+  
+
+   // 查询并加载问题列表的函数
+   async loadQuestionsList() {
+    let query = new CloudQuery("Questions");
+    this.questionsList = await query.find();
+    // 加载选项列表
+
+   // 打印加载的问题列表
+   console.log("加载的问题列表:", this.questionsList);
+
+
+    await this.loadOptionsList(); // 调用加载选项的函数
+
+  }
+
+  // 查询并加载选项列表的函数
+  async loadOptionsList() {
+    let query = new CloudQuery("option");
+    this.optionList = await query.find();
+
+
+
+     // 打印加载的选项列表
+     console.log("加载的选项列表:", this.optionList);
+  }
+
+  // 根据问题 ID 获取相关选项
+  getOptionsForQuestion(questionId: string) {
+    return this.optionList.filter(option => 
+      option.get('question').objectId === questionId
+    );
+  }
+
+
+
+
+ 
+   
+
+}

+ 3 - 4
heartvoice-app/src/app/tab1/tab1.page.html

@@ -21,7 +21,7 @@
       <img src="assets/img/2.png" alt="心理健康" width="130" height="70" />
       <h2>关注你的心理健康</h2>
       <p>个性化心理支持,随时随地</p>
-      <ion-button expand="full" routerLink="/personality-test">开始测试</ion-button>
+      <ion-button expand="full" routerLink="/personality-test" >开始测试</ion-button>
       <h2>随时与AI聊天</h2>
       <p>24/7提供个性化心理疏通对话。</p>
       <ion-button expand="full"  (click)="goTo()" >开始聊天</ion-button>
@@ -40,7 +40,7 @@
           <ion-card-content>
             通过科学的测试了解你的性格偏向。
           </ion-card-content>
-          <ion-button expand="full" routerLink="/personality-test">开始测试</ion-button>
+          <ion-button expand="full" (click)="personality()">开始测试</ion-button>
         </ion-card>
       </ion-col>
       <ion-col size="4">
@@ -52,8 +52,7 @@
           <ion-card-content>
             24/7提供个性化心理疏通对话。
           </ion-card-content>
-          <ion-button expand="full" 
-          >开始聊天</ion-button>
+          <ion-button expand="full" (click)="liaoTian()">开始聊天</ion-button>
         </ion-card>
       </ion-col>
       <ion-col size="4">

+ 12 - 1
heartvoice-app/src/app/tab1/tab1.page.scss

@@ -8,7 +8,7 @@ ion-header {
   ion-title{
     font-family: "宋体";
     font-weight: bold;
-    font-size:larger;
+    font: size 20px;
   }
   ion-toolbar {
     --background: #c3f0b6; /* 顶部工具栏背景色 */
@@ -95,4 +95,15 @@ ion-header {
     ion-card-title {
       font-size: 1rem; /* 小屏幕卡片标题字体大小 */
     }
+  }
+
+
+  app-edit-tag {
+    display: block; /* 使组件占据整个行 */
+    margin: 20px 0; /* 上下外边距 */
+    padding: 10px; /* 内边距 */
+    background-color: rgba(255, 221, 51, 0.1); /* 淡黄色背景 */
+    border: 1px solid rgba(255, 221, 51, 0.5); /* 边框颜色 */
+    border-radius: 8px; /* 圆角边框 */
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 阴影效果 */
   }

+ 8 - 1
heartvoice-app/src/app/tab1/tab1.page.ts

@@ -4,6 +4,7 @@ import { ExploreContainerComponent } from '../explore-container/explore-containe
 import { EditTagComponent } from '../edit-tag/edit-tag.component';
 import { EditRatingStarComponent } from '../edit-rating-star/edit-rating-star.component';
 import {  Router } from '@angular/router';
+import { PersonalityTestComponent } from '../personality-test/personality-test.component';
 
 
 
@@ -13,7 +14,7 @@ import {  Router } from '@angular/router';
   styleUrls: ['tab1.page.scss'],
   standalone: true,
   imports: [IonHeader, IonToolbar, IonTitle, IonContent,IonButton,IonButtons,IonRow,IonCol,IonIcon,IonCard,IonCardHeader,IonCardContent,IonCardTitle,IonList,IonItem,IonLabel,IonGrid,
-    IonAvatar,IonFooter,EditTagComponent, ExploreContainerComponent,EditRatingStarComponent],
+    IonAvatar,IonFooter,EditTagComponent, ExploreContainerComponent,EditRatingStarComponent,PersonalityTestComponent],
 })
 export class Tab1Page {
 
@@ -22,6 +23,12 @@ export class Tab1Page {
    goTo(){
     this.router.navigate(['/tabs/interlocution'])
    }
+   liaoTian(){
+    this.router.navigate(['/tabs/gexinhualiaotian'])
+   }
+   personality(){
+    this.router.navigate(['/tabs/personality-test'])
+   }
    
 
 

+ 1 - 4
heartvoice-app/src/app/tab2/tab2.page.html

@@ -107,9 +107,6 @@
 
 <ion-footer>
   <ion-toolbar>
-    <ion-buttons slot="start">
-      <ion-button routerLink="/home">返回首页</ion-button>
-    </ion-buttons>
-    <ion-title>© 2024 心理健康服务平台</ion-title>
+    <ion-title id="a">© 2024 心理健康服务平台</ion-title>
   </ion-toolbar>
 </ion-footer>

+ 13 - 4
heartvoice-app/src/app/tab2/tab2.page.scss

@@ -1,11 +1,14 @@
+ion-toolbar {
+  --background: #c3f0b6; /* 顶部工具栏背景色 */
+}
+
 ion-content {
-    --background: #c3f0b6; /* 设置背景颜色 */
+    --background: #eefae7; /* 设置背景颜色 */
     padding: 20px; /* 添加内边距 */
     display: flex;
     flex-direction: column;
     align-items: center; /* 居中对齐内容 */
   }
-  
   ion-card {
     width: 100%; /* 卡片宽度 */
     max-width: 600px; /* 最大宽度 */
@@ -15,7 +18,7 @@ ion-content {
   }
   
   ion-card-header {
-    background-color: #fff; /* 卡片头部背景色 */
+    background-color: #f2f6f2; /* 卡片头部背景色 */
     border-top-left-radius: 10px; /* 左上角圆角 */
     border-top-right-radius: 10px; /* 右上角圆角 */
   }
@@ -31,7 +34,13 @@ ion-content {
     background-color: #e8f4a7; /* 列表项背景色 */
     box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 列表项阴影效果 */
   }
-  
+  ion-title{
+    font-family: "宋体";
+    font-weight: bold;
+    font-size: 30px;
+    text-align: center; /* 文本居中 */
+  }
+
   ion-avatar {
     border-radius: 50%; /* 头像圆形 */
   }

+ 28 - 12
heartvoice-app/src/app/tab3/tab3.page.html

@@ -1,17 +1,33 @@
-<ion-header [translucent]="true">
+<ion-header>
   <ion-toolbar>
-    <ion-title>
-      Tab 3
-    </ion-title>
+    <ion-title>我的</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>
+<ion-content>
+  <!-- 个人信息名片 -->
+  <ion-card>
+    <ion-card-header>
+      <ion-card-title>个人信息</ion-card-title>
+    </ion-card-header>
+    <ion-card-content>
+      <ion-item>
+        <ion-avatar slot="start">
+          <img src="assets/img/1.png" alt="用户头像" />
+        </ion-avatar>
+        <ion-label>
+          <h2>张三</h2>
+          <p>心理健康爱好者</p>
+        </ion-label>
+      </ion-item>
+      <ion-button expand="full" color="primary" routerLink="/edit-profile">编辑个人信息</ion-button>
+    </ion-card-content>
+  </ion-card>
 
-  <app-explore-container name="Tab 3 page"></app-explore-container>
-</ion-content>
+  <!-- 列表清单 -->
+  <ion-list>
+    
+
+  </ion-list>
+
+  

+ 53 - 0
heartvoice-app/src/app/tab3/tab3.page.scss

@@ -0,0 +1,53 @@
+ion-toolbar {
+    --background: #c3f0b6; /* 顶部工具栏背景色 */
+  }
+  ion-title{
+    font-family: "宋体";
+    font-weight: bold;
+    font-size: 20px;
+    text-align: center; /* 文本居中 */
+    color: #333; /* 字体颜色 */
+  }
+  /* 个人信息名片的样式 */
+  ion-card {
+    margin: 16px; /* 外边距 */
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
+  }
+  
+  /* 个人信息名片内容的样式 */
+  ion-card-content {
+    padding: 16px; /* 内边距 */
+  }
+  
+  /* 列表项的悬浮效果 */
+  ion-item:hover {
+    background-color: rgba(0, 0, 0, 0.05); /* 悬浮时背景色 */
+  }
+  
+  /* 显示历史记录和反馈问题的卡片样式 */
+  ion-card {
+    margin: 16px; /* 外边距 */
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
+  }
+  
+  /* 列表内容的样式 */
+  ion-label h2 {
+    font-size: 18px; /* 标题字体大小 */
+    margin: 0; /* 去掉默认外边距 */
+  }
+  
+  ion-label p {
+    font-size: 14px; /* 描述字体大小 */
+    color: #666; /* 描述字体颜色 */
+  }
+  
+  /* 提交反馈按钮的样式 */
+  ion-button {
+    margin-top: 10px; /* 上边距 */
+  }
+  
+  /* 控制卡片的显示效果 */
+  ion-card-header {
+    background-color: #e0e0e0; /* 背景色 */
+    border-bottom: 1px solid #ccc; /* 底部边框 */
+  }

+ 1 - 0
heartvoice-app/src/app/tab3/tab3.page.spec.ts

@@ -16,3 +16,4 @@ describe('Tab3Page', () => {
     expect(component).toBeTruthy();
   });
 });
+

+ 24 - 4
heartvoice-app/src/app/tab3/tab3.page.ts

@@ -1,14 +1,34 @@
-import { Component } from '@angular/core';
-import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
+import { Component, NgModule } from '@angular/core';
+import { IonCardContent,IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardHeader, IonCardTitle, IonItem, IonAvatar, IonLabel, IonButton, IonList, IonIcon } from '@ionic/angular/standalone';
 import { ExploreContainerComponent } from '../explore-container/explore-container.component';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { IonicModule } from '@ionic/angular';
+
 
 @Component({
   selector: 'app-tab3',
   templateUrl: 'tab3.page.html',
   styleUrls: ['tab3.page.scss'],
   standalone: true,
-  imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent],
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent,
+  IonCard,IonCardContent,IonCardHeader,IonCardTitle,IonItem,IonAvatar,IonLabel,IonButton,IonList,IonIcon,],
 })
 export class Tab3Page {
-  constructor() {}
+  historyRecords = [
+    { title: '性格测试结果', date: new Date('2024-01-01') },
+    { title: '心情分析报告', date: new Date('2024-01-15') },
+    { title: 'AI心理疏通记录', date: new Date('2024-02-05') },
+  ];
+
+  // 示例反馈问题数据
+  feedbackList = [
+    { title: '反馈关于应用崩溃', status: '已解决' },
+    { title: '建议增加新功能', status: '待处理' },
+  ];
+
+  // 控制显示的状态
+  showHistory = false;
+  showFeedback = false;
 }
+

+ 10 - 0
heartvoice-app/src/app/tabs/tabs.routes.ts

@@ -26,6 +26,16 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../interlocution/interlocution.component').then((m) => m.InterlocutionComponent),
       },
+      {
+        path: 'gexinhualiaotian',
+        loadComponent: () =>
+          import('../gexinhualiaotian/gexinhualiaotian.component').then((m) => m.GexinhualiaotianComponent),
+      },
+      {
+        path: 'personality-test',
+        loadComponent: () =>
+          import('../personality-test/personality-test.component').then((m) => m.PersonalityTestComponent),
+      },
       {
         path: '',
         redirectTo: '/tabs/tab1',

+ 194 - 0
heartvoice-app/src/lib/ncloud.ts

@@ -0,0 +1,194 @@
+// CloudObject.ts
+export class CloudObject {
+    className: string;
+    id: string | null = null;
+    createdAt:any;
+    updatedAt:any;
+    data: Record<string, any> = {};
+
+    constructor(className: string) {
+        this.className = className;
+    }
+
+    toPointer() {
+        return { "__type": "Pointer", "className": this.className, "objectId": this.id };
+    }
+
+    set(json: Record<string, any>) {
+        Object.keys(json).forEach(key => {
+            if (["objectId", "id", "createdAt", "updatedAt", "ACL"].indexOf(key) > -1) {
+                return;
+            }
+            this.data[key] = json[key];
+        });
+    }
+
+    get(key: string) {
+        return this.data[key] || null;
+    }
+
+    async save() {
+        let method = "POST";
+        let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}`;
+
+        // 更新
+        if (this.id) {
+            url += `/${this.id}`;
+            method = "PUT";
+        }
+
+        const body = JSON.stringify(this.data);
+        const response = await fetch(url, {
+            headers: {
+                "content-type": "application/json;charset=UTF-8",
+                "x-parse-application-id": "dev"
+            },
+            body: body,
+            method: method,
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const result = await response?.json();
+        if (result?.error) {
+            console.error(result?.error);
+        }
+        if (result?.objectId) {
+            this.id = result?.objectId;
+        }
+        return this;
+    }
+
+    async destroy() {
+        if (!this.id) return;
+        const response = await fetch(`http://dev.fmode.cn:1337/parse/classes/${this.className}/${this.id}`, {
+            headers: {
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "DELETE",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const result = await response?.json();
+        if (result) {
+            this.id = null;
+        }
+        return true;
+    }
+}
+
+// CloudQuery.ts
+export class CloudQuery {
+    className: string;
+    whereOptions: Record<string, any> = {};
+
+    constructor(className: string) {
+        this.className = className;
+    }
+
+    greaterThan(key: string, value: any) {
+        if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        this.whereOptions[key]["$gt"] = value;
+    }
+
+    greaterThanAndEqualTo(key: string, value: any) {
+        if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        this.whereOptions[key]["$gte"] = value;
+    }
+
+    lessThan(key: string, value: any) {
+        if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        this.whereOptions[key]["$lt"] = value;
+    }
+
+    lessThanAndEqualTo(key: string, value: any) {
+        if (!this.whereOptions[key]) this.whereOptions[key] = {};
+        this.whereOptions[key]["$lte"] = value;
+    }
+
+    equalTo(key: string, value: any) {
+        this.whereOptions[key] = value;
+    }
+
+    async get(id: string) {
+        const url = `http://dev.fmode.cn:1337/parse/classes/${this.className}/${id}?`;
+
+        const response = await fetch(url, {
+            headers: {
+                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "GET",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const json = await response?.json();
+        return json || {};
+    }
+
+    async find() {
+        let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}?`;
+
+        if (Object.keys(this.whereOptions).length) {
+            const whereStr = JSON.stringify(this.whereOptions);
+            url += `where=${whereStr}`;
+        }
+
+        const response = await fetch(url, {
+            headers: {
+                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "GET",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const json = await response?.json();
+        let list = json?.results || []
+        let objList = list.map((item:any)=>this.dataToObj(item))
+        return objList || [];
+    }
+
+    async first() {
+        let url = `http://dev.fmode.cn:1337/parse/classes/${this.className}?`;
+
+        if (Object.keys(this.whereOptions).length) {
+            const whereStr = JSON.stringify(this.whereOptions);
+            url += `where=${whereStr}`;
+        }
+
+        const response = await fetch(url, {
+            headers: {
+                "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+                "x-parse-application-id": "dev"
+            },
+            body: null,
+            method: "GET",
+            mode: "cors",
+            credentials: "omit"
+        });
+
+        const json = await response?.json();
+        const exists = json?.results?.[0] || null;
+        if (exists) {
+            let existsObject = this.dataToObj(exists)
+            return existsObject;
+        }
+        return null
+    }
+
+    dataToObj(exists:any):CloudObject{
+        let existsObject = new CloudObject(this.className);
+        existsObject.set(exists);
+        existsObject.id = exists.objectId;
+        existsObject.createdAt = exists.createdAt;
+        existsObject.updatedAt = exists.updatedAt;
+        return existsObject;
+    }
+}

+ 163 - 0
heartvoice-server/lib/ncloud.js

@@ -0,0 +1,163 @@
+class CloudObject{
+    id
+    className
+    data = {}
+    constructor(className){
+        this.className = className
+    }
+    toPointer(){
+        return {"__type":"Pointer","className":this.className,"objectId":this.id}
+    }
+    set(json){
+        Object.keys(json).forEach(key=>{
+            if(["objectId","id","createdAt","updatedAt","ACL"].indexOf(key)>-1){
+                return
+            }
+            this.data[key] = json[key]
+        })
+    }
+    get(key){
+        return this.data[key] || null
+    }
+    async save(){
+        let method = "POST"
+        let url = "http://dev.fmode.cn:1337/parse/classes/" + this.className
+        // 更新
+        if(this.id){
+            url += "/"+this.id
+            method = "PUT"
+        } 
+        let body = JSON.stringify(this.data)
+        let response = await fetch(url, {
+            "headers": {
+              "content-type": "application/json;charset=UTF-8",
+              "x-parse-application-id": "dev"
+            },
+            "body": body,
+            "method": method,
+            "mode": "cors",
+            "credentials": "omit"
+          });
+          let result = await response?.json();
+          if(result?.error){
+            console.error(result?.error)
+          }
+          if(result?.objectId){this.id = result?.objectId}
+          return this
+    }
+    async destory(){
+        if(!this.id) return
+        let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Doctor/"+this.id, {
+            "headers": {
+              "x-parse-application-id": "dev"
+            },
+            "body": null,
+            "method": "DELETE",
+            "mode": "cors",
+            "credentials": "omit"
+          });
+          let result = await response?.json();
+          if(result){
+            this.id = null
+        }
+        return true
+    }
+}
+
+class CloudQuery{
+    className
+    constructor(className){
+        this.className = className
+    }
+
+    whereOptions = {}
+    greaterThan(key,value){
+        if(!this.whereOptions[key]) this.whereOptions[key] = {}
+        this.whereOptions[key]["$gt"] = value
+    }
+    greaterThanAndEqualTo(key,value){
+        if(!this.whereOptions[key]) this.whereOptions[key] = {}
+        this.whereOptions[key]["$gte"] = value
+    }
+    lessThan(key,value){
+        if(!this.whereOptions[key]) this.whereOptions[key] = {}
+        this.whereOptions[key]["$lt"] = value
+    }
+    lessThanAndEqualTo(key,value){
+        if(!this.whereOptions[key]) this.whereOptions[key] = {}
+        this.whereOptions[key]["$lte"] = value
+    }
+    equalTo(key,value){
+        this.whereOptions[key] = value
+    }
+
+    async get(id){
+        let url = "http://dev.fmode.cn:1337/parse/classes/"+this.className+"/"+id+"?"
+
+        let response = await fetch(url, {
+            "headers": {
+            "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+            "x-parse-application-id": "dev"
+            },
+            "body": null,
+            "method": "GET",
+            "mode": "cors",
+            "credentials": "omit"
+        });
+        let json = await response?.json();
+        return json || {}
+    }
+    async find(){
+        let url = "http://dev.fmode.cn:1337/parse/classes/"+this.className+"?"
+        
+        if(Object.keys(this.whereOptions)?.length){
+            let whereStr = JSON.stringify(this.whereOptions)
+            url += `where=${whereStr}`
+        }
+
+        let response = await fetch(url, {
+            "headers": {
+            "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+            "x-parse-application-id": "dev"
+            },
+            "body": null,
+            "method": "GET",
+            "mode": "cors",
+            "credentials": "omit"
+        });
+        let json = await response?.json();
+        return json?.results || []
+    }
+    async first(){
+        let url = "http://dev.fmode.cn:1337/parse/classes/"+this.className+"?"
+        
+        if(Object.keys(this.whereOptions)?.length){
+            let whereStr = JSON.stringify(this.whereOptions)
+            url += `where=${whereStr}`
+        }
+
+        let response = await fetch(url, {
+            "headers": {
+            "if-none-match": "W/\"1f0-ghxH2EwTk6Blz0g89ivf2adBDKY\"",
+            "x-parse-application-id": "dev"
+            },
+            "body": null,
+            "method": "GET",
+            "mode": "cors",
+            "credentials": "omit"
+        });
+        let json = await response?.json();
+        let exists = json?.results?.[0] || null
+        if(exists){
+            let existsObject = new CloudObject(this.className)
+            existsObject.set(exists)
+            existsObject.id = exists.objectId
+            existsObject.createdAt = exists.createdAt
+            existsObject.updatedAt = exists.updatedAt
+            return existsObject
+        }
+    }
+}
+
+module.exports.CloudObject = CloudObject
+module.exports.CloudQuery = CloudQuery

+ 1482 - 0
heartvoice-server/migration/data.js

@@ -0,0 +1,1482 @@
+module.exports.Questionslist =  [
+    {
+      "objectId": 1,
+      "questionText": "当你遇到新朋友时,你 A:说话比聆听的时间多 B:聆听比说话的时间多",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 2,
+      "questionText": "在社交场合中,你更倾向于 A:主动与人交谈 B:观察他人并参与",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 3,
+      "questionText": "你更喜欢 A:与人合作完成任务 B:独自完成任务",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 4,
+      "questionText": "你更享受 A:参加聚会和活动 B:在家看书或看电影",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 5,
+      "questionText": "在工作中,你更倾向于 A:与同事交流想法 B:独立思考",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 6,
+      "questionText": "你更喜欢 A:通过谈话解决问题 B:通过思考解决问题",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 7,
+      "questionText": "在团队中,你更喜欢 A:带领团队 B:支持团队",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 8,
+      "questionText": "你更倾向于 A:与人分享自己的想法 B:保留自己的想法",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 9,
+      "questionText": "在讨论中,你更喜欢 A:积极参与 B:倾听并思考",
+      "dimension": "E/I"
+    },
+    {
+      "objectId": 10,
+      "questionText": "你更喜欢 A:计划并组织活动 B:随意参加活动",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 11,
+      "questionText": "你更倾向于 A:遵循计划 B:灵活处理事情",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 12,
+      "questionText": "在工作中,你更喜欢 A:有明确的截止日期 B:没有固定的截止日期",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 13,
+      "questionText": "你更享受 A:提前安排所有事情 B:即兴发挥",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 14,
+      "questionText": "你更倾向于 A:有条理的工作 B:自由的工作",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 15,
+      "questionText": "你更喜欢 A:制定详细的计划 B:根据情况调整计划",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 16,
+      "questionText": "在生活中,你更倾向于 A:事先安排好一切 B:随遇而安",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 17,
+      "questionText": "你更喜欢 A:有结构的环境 B:灵活的环境",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 18,
+      "questionText": "你在工作中更倾向于 A:有条理的步骤 B:随机应变",
+      "dimension": "J/P"
+    },
+    {
+      "objectId": 19,
+      "questionText": "在做决定时,你更倾向于 A:依靠逻辑和数据 B:依靠直觉和感觉",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 20,
+      "questionText": "在讨论中,你更喜欢 A:分析问题 B:理解他人的感受",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 21,
+      "questionText": "你更倾向于 A:客观地看待事情 B:主观地看待事情",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 22,
+      "questionText": "在工作中,你更重视 A:效率和目标 B:人际关系和氛围",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 23,
+      "questionText": "你在做决策时更倾向于 A:考虑事实 B:考虑影响他人的感受",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 24,
+      "questionText": "在团队中,你更倾向于 A:提出理性的建议 B:关注团队的情感",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 25,
+      "questionText": "你更喜欢 A:明确的规则 B:灵活的原则",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 26,
+      "questionText": "在工作中,你更倾向于 A:追求客观真理 B:追求和谐关系",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 27,
+      "questionText": "你更喜欢 A:直接的反馈 B:温和的反馈",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 28,
+      "questionText": "在处理问题时,你更倾向于 A:分析所有数据 B:考虑情感因素",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 29,
+      "questionText": "你在生活中更倾向于 A:追求逻辑和效率 B:追求和谐与理解",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 30,
+      "questionText": "你更喜欢 A:与人交流想法 B:与人交流感受",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 31,
+      "questionText": "在工作中,你更倾向于 A:追求目标 B:关注团队氛围",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 32,
+      "questionText": "在选择职业时更倾向于 A:选择有挑战性的工作 B:选择让人愉快的工作",
+      "dimension": "T/F"
+    },
+    {
+      "objectId": 33,
+      "questionText": "你更倾向于 A:依靠事实 B:依靠直觉",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 34,
+      "questionText": "在解决问题时,你更喜欢 A:使用已知的方法 B:尝试新的方法",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 35,
+      "questionText": "你更倾向于 A:关注细节 B:关注整体",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 36,
+      "questionText": "你在学习时更喜欢 A:具体的实例 B:抽象的概念",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 37,
+      "questionText": "你更倾向于 A:遵循传统 B:探索新事物",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 38,
+      "questionText": "在工作中,你更喜欢 A:按部就班 B:跳出框架",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 39,
+      "questionText": "你在交流中更倾向于 A:使用具体的语言 B:使用隐喻和比喻",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 40,
+      "questionText": "在决策时,你更倾向于 A:依靠经验 B:依靠直觉",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 41,
+      "questionText": "在思考过程中,你更倾向于 A:逻辑推理 B:直觉联想",
+      "dimension": "S/N"
+    },
+    {
+      "objectId": 42,
+      "questionText": "在生活中,你更倾向于 A:实事求是 B:追求可能性",
+      "dimension": "S/N"
+    }
+  ]
+
+  
+
+
+
+
+
+module.exports.optionlist = [
+    {
+      "objectId": 1,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "1" }
+    },
+    {
+      "objectId": 2,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "1" }
+    },
+    {
+      "objectId": 3,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "1" }
+    },
+    {
+      "objectId": 4,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "1" }
+    },
+    {
+      "objectId": 5,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "1" }
+    },
+    {
+      "objectId": 6,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "2" }
+    },
+    {
+      "objectId": 7,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "2" }
+    },
+    {
+      "objectId": 8,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "2" }
+    },
+    {
+      "objectId": 9,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "2" }
+    },
+    {
+      "objectId": 10,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "2" }
+    },
+    {
+      "objectId": 11,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "3" }
+    },
+    {
+      "objectId": 12,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "3" }
+    },
+    {
+      "objectId": 13,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "3" }
+    },
+    {
+      "objectId": 14,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "3" }
+    },
+    {
+      "objectId": 15,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "3" }
+    },
+    {
+      "objectId": 16,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "4" }
+    },
+    {
+      "objectId": 17,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "4" }
+    },
+    {
+      "objectId": 18,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "4" }
+    },
+    {
+      "objectId": 19,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "4" }
+    },
+    {
+      "objectId": 20,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "4" }
+    },
+    {
+      "objectId": 21,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "5" }
+    },
+    {
+      "objectId": 22,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "5" }
+    },
+    {
+      "objectId": 23,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "5" }
+    },
+    {
+      "objectId": 24,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "5" }
+    },
+    {
+      "objectId": 25,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "5" }
+    },
+    {
+      "objectId": 26,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "6" }
+    },
+    {
+      "objectId": 27,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "6" }
+    },
+    {
+      "objectId": 28,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "6" }
+    },
+    {
+      "objectId": 29,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "6" }
+    },
+    {
+      "objectId": 30,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "6" }
+    },
+    {
+      "objectId": 31,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "7" }
+    },
+    {
+      "objectId": 32,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "7" }
+    },
+    {
+      "objectId": 33,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "7" }
+    },
+    {
+      "objectId": 34,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "7" }
+    },
+    {
+      "objectId": 35,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "7" }
+    },
+    {
+      "objectId": 36,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "8" }
+    },
+    {
+      "objectId": 37,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "8" }
+    },
+    {
+      "objectId": 38,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "8" }
+    },
+    {
+      "objectId": 39,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "8" }
+    },
+    {
+      "objectId": 40,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "8" }
+    },
+    {
+      "objectId": 41,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "9" }
+    },
+    {
+      "objectId": 42,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "9" }
+    },
+    {
+      "objectId": 43,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "9" }
+    },
+    {
+      "objectId": 44,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "9" }
+    },
+    {
+      "objectId": 45,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "9" }
+    },
+    {
+      "objectId": 46,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "10" }
+    },
+    {
+      "objectId": 47,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "10" }
+    },
+    {
+      "objectId": 48,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "10" }
+    },
+    {
+      "objectId": 49,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "10" }
+    },
+    {
+      "objectId": 50,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "10" }
+    },
+    {
+      "objectId": 51,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "11" }
+    },
+    {
+      "objectId": 52,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "11" }
+    },
+    {
+      "objectId": 53,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "11" }
+    },
+    {
+      "objectId": 54,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "11" }
+    },
+    {
+      "objectId": 55,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "11" }
+    },
+    {
+      "objectId": 56,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "12" }
+    },
+    {
+      "objectId": 57,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "12" }
+    },
+    {
+      "objectId": 58,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "12" }
+    },
+    {
+      "objectId": 59,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "12" }
+    },
+    {
+      "objectId": 60,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "12" }
+    },
+    {
+      "objectId": 61,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "13" }
+    },
+    {
+      "objectId": 62,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "13" }
+    },
+    {
+      "objectId": 63,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "13" }
+    },
+    {
+      "objectId": 64,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "13" }
+    },
+    {
+      "objectId": 65,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "13" }
+    },
+    {
+      "objectId": 66,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "14" }
+    },
+    {
+      "objectId": 67,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "14" }
+    },
+    {
+      "objectId": 68,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "14" }
+    },
+    {
+      "objectId": 69,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "14" }
+    },
+    {
+      "objectId": 70,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "14" }
+    },
+    {
+      "objectId": 71,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "15" }
+    },
+    {
+      "objectId": 72,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "15" }
+    },
+    {
+      "objectId": 73,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "15" }
+    },
+    {
+      "objectId": 74,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "15" }
+    },
+    {
+      "objectId": 75,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "15" }
+    },
+    {
+      "objectId": 76,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "16" }
+    },
+    {
+      "objectId": 77,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "16" }
+    },
+    {
+      "objectId": 78,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "16" }
+    },
+    {
+      "objectId": 79,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "16" }
+    },
+    {
+      "objectId": 80,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "16" }
+    },
+    {
+      "objectId": 81,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "17" }
+    },
+    {
+      "objectId": 82,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "17" }
+    },
+    {
+      "objectId": 83,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "17" }
+    },
+    {
+      "objectId": 84,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "17" }
+    },
+    {
+      "objectId": 85,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "17" }
+    },
+    {
+      "objectId": 86,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "18" }
+    },
+    {
+      "objectId": 87,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "18" }
+    },
+    {
+      "objectId": 88,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "18" }
+    },
+    {
+      "objectId": 89,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "18" }
+    },
+    {
+      "objectId": 90,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "18" }
+    },
+    {
+      "objectId": 91,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "19" }
+    },
+    {
+      "objectId": 92,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "19" }
+    },
+    {
+      "objectId": 93,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "19" }
+    },
+    {
+      "objectId": 94,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "19" }
+    },
+    {
+      "objectId": 95,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "19" }
+    },
+    {
+      "objectId": 96,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "20" }
+    },
+    {
+      "objectId": 97,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "20" }
+    },
+    {
+      "objectId": 98,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "20" }
+    },
+    {
+      "objectId": 99,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "20" }
+    },
+    {
+      "objectId": 100,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "20" }
+    },
+    {
+      "objectId": 101,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "21" }
+    },
+    {
+      "objectId": 102,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "21" }
+    },
+    {
+      "objectId": 103,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "21" }
+    },
+    {
+      "objectId": 104,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "21" }
+    },
+    {
+      "objectId": 105,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "21" }
+    },
+    {
+      "objectId": 106,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "22" }
+    },
+    {
+      "objectId": 107,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "22" }
+    },
+    {
+      "objectId": 108,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "22" }
+    },
+    {
+      "objectId": 109,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "22" }
+    },
+    {
+      "objectId": 110,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "22" }
+    },
+    {
+      "objectId": 111,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "23" }
+    },
+    {
+      "objectId": 112,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "23" }
+    },
+    {
+      "objectId": 113,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "23" }
+    },
+    {
+      "objectId": 114,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "23" }
+    },
+    {
+      "objectId": 115,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "23" }
+    },
+    {
+      "objectId": 116,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "24" }
+    },
+    {
+      "objectId": 117,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "24" }
+    },
+    {
+      "objectId": 118,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "24" }
+    },
+    {
+      "objectId": 119,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "24" }
+    },
+    {
+      "objectId": 120,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "24" }
+    },
+    {
+      "objectId": 121,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "25" }
+    },
+    {
+      "objectId": 122,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "25" }
+    },
+    {
+      "objectId": 123,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "25" }
+    },
+    {
+      "objectId": 124,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "25" }
+    },
+    {
+      "objectId": 125,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "25" }
+    },
+    {
+      "objectId": 126,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "26" }
+    },
+    {
+      "objectId": 127,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "26" }
+    },
+    {
+      "objectId": 128,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "26" }
+    },
+    {
+      "objectId": 129,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "26" }
+    },
+    {
+      "objectId": 130,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "26" }
+    },
+    {
+      "objectId": 131,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "27" }
+    },
+    {
+      "objectId": 132,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "27" }
+    },
+    {
+      "objectId": 133,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "27" }
+    },
+    {
+      "objectId": 134,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "27" }
+    },
+    {
+      "objectId": 135,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "27" }
+    },
+    {
+      "objectId": 136,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "28" }
+    },
+    {
+      "objectId": 137,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "28" }
+    },
+    {
+      "objectId": 138,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "28" }
+    },
+    {
+      "objectId": 139,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "28" }
+    },
+    {
+      "objectId": 140,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "28" }
+    },
+    {
+      "objectId": 141,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "29" }
+    },
+    {
+      "objectId": 142,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "29" }
+    },
+    {
+      "objectId": 143,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "29" }
+    },
+    {
+      "objectId": 144,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "29" }
+    },
+    {
+      "objectId": 145,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "29" }
+    },
+    {
+      "objectId": 146,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "30" }
+    },
+    {
+      "objectId": 147,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "30" }
+    },
+    {
+      "objectId": 148,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "30" }
+    },
+    {
+      "objectId": 149,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "30" }
+    },
+    {
+      "objectId": 150,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "30" }
+    },
+    {
+      "objectId": 151,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "31" }
+    },
+    {
+      "objectId": 152,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "31" }
+    },
+    {
+      "objectId": 153,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "31" }
+    },
+    {
+      "objectId": 154,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "31" }
+    },
+    {
+      "objectId": 155,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "31" }
+    },
+    {
+      "objectId": 156,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "32" }
+    },
+    {
+      "objectId": 157,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "32" }
+    },
+    {
+      "objectId": 158,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "32" }
+    },
+    {
+      "objectId": 159,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "32" }
+    },
+    {
+      "objectId": 160,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "32" }
+    },
+    {
+      "objectId": 161,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "33" }
+    },
+    {
+      "objectId": 162,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "33" }
+    },
+    {
+      "objectId": 163,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "33" }
+    },
+    {
+      "objectId": 164,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "33" }
+    },
+    {
+      "objectId": 165,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "33" }
+    },
+    {
+      "objectId": 166,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "34" }
+    },
+    {
+      "objectId": 167,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "34" }
+    },
+    {
+      "objectId": 168,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "34" }
+    },
+    {
+      "objectId": 169,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "34" }
+    },
+    {
+      "objectId": 170,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "34" }
+    },
+    {
+      "objectId": 171,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "35" }
+    },
+    {
+      "objectId": 172,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "35" }
+    },
+    {
+      "objectId": 173,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "35" }
+    },
+    {
+      "objectId": 174,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "35" }
+    },
+    {
+      "objectId": 175,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "35" }
+    },
+    {
+      "objectId": 176,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "36" }
+    },
+    {
+      "objectId": 177,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "36" }
+    },
+    {
+      "objectId": 178,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "36" }
+    },
+    {
+      "objectId": 179,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "36" }
+    },
+    {
+      "objectId": 180,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "36" }
+    },
+    {
+      "objectId": 181,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "37" }
+    },
+    {
+      "objectId": 182,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "37" }
+    },
+    {
+      "objectId": 183,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "37" }
+    },
+    {
+      "objectId": 184,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "37" }
+    },
+    {
+      "objectId": 185,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "37" }
+    },
+    {
+      "objectId": 186,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "38" }
+    },
+    {
+      "objectId": 187,
+      "optionText": "非��像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "38" }
+    },
+    {
+      "objectId": 188,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "38" }
+    },
+    {
+      "objectId": 189,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "38" }
+    },
+    {
+      "objectId": 190,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "38" }
+    },
+    {
+      "objectId": 191,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "39" }
+    },
+    {
+      "objectId": 192,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "39" }
+    },
+    {
+      "objectId": 193,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "39" }
+    },
+    {
+      "objectId": 194,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "39" }
+    },
+    {
+      "objectId": 195,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "39" }
+    },
+    {
+      "objectId": 196,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "40" }
+    },
+    {
+      "objectId": 197,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "40" }
+    },
+    {
+      "objectId": 198,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "40" }
+    },
+    {
+      "objectId": 199,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "40" }
+    },
+    {
+      "objectId": 200,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "40" }
+    },
+    {
+      "objectId": 201,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "41" }
+    },
+    {
+      "objectId": 202,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "41" }
+    },
+    {
+      "objectId": 203,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "41" }
+    },
+    {
+      "objectId": 204,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "41" }
+    },
+    {
+      "objectId": 205,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "41" }
+    },
+    {
+      "objectId": 206,
+      "optionText": "比较像A",
+      "weight": "0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "42" }
+    },
+    {
+      "objectId": 207,
+      "optionText": "非常像A",
+      "weight": "1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "42" }
+    },
+    {
+      "objectId": 208,
+      "optionText": "居中",
+      "weight": "0",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "42" }
+    },
+    {
+      "objectId": 209,
+      "optionText": "比较像B",
+      "weight": "-0.5",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "42" }
+    },
+    {
+      "objectId": 210,
+      "optionText": "非常像B",
+      "weight": "-1",
+      "question": { "__type": "Pointer", "className": "Question", "objectId": "42" }
+    }
+  ]
+

+ 277 - 0
heartvoice-server/migration/import-data.js

@@ -0,0 +1,277 @@
+
+//const { CloudQuery, CloudObject } = require("../lib/ncloud");
+// testCRUD()
+// //testQuery()
+// async function testQuery(){
+//     let query = new CloudQuery("Doctor")
+//     // query.equalTo("gender","女")
+//     query.greaterThanAndEqualTo("age",40)
+//     query.lessThan("age",41)
+//     let list = await query.find();
+//     console.log(list)
+// }
+
+// async function testCRUD(){
+//     // 基本的增删查改测试
+//     let query = new CloudQuery("Questions")
+//     let QuestionsList = await query.find();
+//     console.log("QuestionsList count",QuestionsList?.length)
+
+//     let newQuestions = new CloudObject("Questions")
+//     newQuestions.set({"questionText":"S"})
+    
+//     newQuestions = await newQuestions.save(newQuestions)
+//     console.log("newQuestions",newQuestions)
+    
+//     //没有改
+//     //destory有问题
+//     await newQuestions.destory()
+//     console.log("newQuestions 已删除",newQuestions)
+// }
+
+
+
+
+
+const { CloudQuery, CloudObject } = require("../lib/ncloud");
+const { Questionslist, optionlist } = require("./data");
+inportQuestionAndtion();
+
+let DataMap = {
+    option: {},
+    Questions: {}
+};
+
+async function inportQuestionAndtion() {
+    // 导入问题数据
+    let questionslist = Questionslist;
+    //console.log("导入的问题列表:", questionslist); // 打印问题列表
+
+    for (let index = 0; index < questionslist.length; index++) {
+        let questions = questionslist[index];
+        questions = await importObject("Questions", questions);
+    }
+
+    // 导入选项数据
+    let optionslist = optionlist;
+    console.log("导入的选项列表:", optionslist); // 打印选项列表
+
+    for (let index = 0; index < optionslist.length; index++) {
+        let options = optionslist[index];
+        options = await importObject("option", options);
+    }
+
+   
+}
+
+async function importObject(className, data) {
+    // 查重 srcId 数据源列表中的 objectId 并非数据库生成的唯一 ID,因此需要有一个 srcId 字段进行记录,并查重
+    let query = new CloudQuery(className);
+    let srcId = data.objectId;
+    query.equalTo("srcId", srcId);
+    let importObj = await query.first();
+    // console.log(importObj); // 可以在这里打印查重结果
+
+    // 导入
+    // 导入前批量处理 Pointer 类型数据,进行重定向
+    Object.keys(data)?.forEach(key => {
+        let field = data[key];
+        let srcId = field?.objectId;
+        if (srcId) { // 是数组字段
+            if (key == "question") {
+                data[key] = DataMap?.["Questions"]?.[srcId]?.toPointer();
+            }
+        }
+    });
+
+    // 若未添加,则创建新对象并保存
+    if (!importObj?.id) {
+        importObj = new CloudObject(className);
+    }
+
+    // 保存或更新数据
+    data.srcId = srcId;
+    importObj.set(data);
+    importObj = await importObj.save();
+
+    DataMap[className][srcId] = importObj;
+
+
+}
+
+
+
+
+
+
+
+
+// const { CloudQuery, CloudObject } = require("../lib/ncloud");
+// const { Questionslist, optionlist } = require("./data");
+// inportQuestionAndtion()
+
+// DataMap = {
+//      option:{},
+//     Questions:{}
+// }
+
+// async function inportQuestionAndtion(){
+//     // 导入科室数据
+//     let questionslist = Questionslist
+//     for (let index = 0; index < questionslist.length; index++) {
+//         let questions = questionslist[index];
+//         questions = await importObject("Questions",questions)
+//     }
+//     // 导入医生数据
+//     let optionslist = optionlist
+//     for (let index = 0; index < optionslist.length; index++) {
+//         let options = optionslist[index];
+//         options = await importObject("option",options)
+//     }
+//      //console.log(DataMap["option"])
+// }
+
+// async function importObject(className,data){
+
+//     // 查重 srcId 数据源列表中的objectId并非数据库生成的唯一ID,因此需要有一个srcId字段进行记录,并查重
+//     let query = new CloudQuery(className)
+//     let srcId = data.objectId
+//     query.equalTo("srcId",srcId)
+//     let importObj = await query.first()
+//     //console.log(importObj)
+
+//     // 导入
+//     // 导入前批量处理Pointer类型数据,进行重定向
+//     Object.keys(data)?.forEach(key=>{
+//         let field = data[key]
+//         let srcId = field?.objectId
+//         if(srcId){ // 是数组字段
+//             if(key=="question"){
+//                 data[key] = DataMap?.["Questions"]?.[srcId]?.toPointer();
+//             }
+//         }
+//     })
+
+//     // 若未添加,则创建新对象并保存
+//     if(!importObj?.id){
+//         importObj = new CloudObject(className)
+//     }
+
+//     // 保存或更新数据
+//     data.srcId = srcId;
+//     importObj.set(data);
+//     importObj = await importObj.save();
+
+//     DataMap[className][srcId] = importObj
+// }
+
+
+
+
+
+
+
+
+
+
+
+// async function main(){
+//     let questionsList = await getquestions();
+//     console.log("questionsList",questionsList);
+//     console.log("questionsList count",questionsList?.length);
+    
+
+//     let newQuestions = { "questionText":"S" }
+//     let newSavedId = await creatquestions(newQuestions)
+//     newQuestions.objectId = newQuestions
+//     console.log("newQuestions",newQuestions)
+
+//     // let updateQuestions = { id:"NYoCWM9cNV" , "questionsText":"St" }
+//     // let updateSavedId = await updatequestions(updateQuestions)
+//     // updateQuestions.objectId = updateQuestions
+//     // console.log("updateQuestions",updateQuestions)
+    
+//     await deleteQuestions(newSavedId)
+//     console.log("newSavedId 已删除",newSavedId)
+    
+// }
+// main()
+
+// async function deleteQuestions(id){
+//   let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Questions/"+ id, {
+//     "headers": {
+//       "accept": "*/*",
+//       "accept-language": "zh-CN,zh;q=0.9",
+//       "x-parse-application-id": "dev"
+//     },
+//     "referrer": "http://127.0.0.1:4040/apps/DevServer/api_console/rest",
+//     "referrerPolicy": "no-referrer-when-downgrade",
+//     "body": null,
+//     "method": "DELETE",
+//     "mode": "cors",
+//     "credentials": "omit"
+//   });
+//     return response?.json();
+// }
+
+
+// async function updatequestions(id,questionsInfo){
+//     let body = JSON.stringify(questionsInfo)
+//     let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Questions/" + id, {
+//         "headers": {
+//           "accept": "*/*",
+//           "accept-language": "zh-CN,zh;q=0.9",
+//           "content-type": "text/plain;charset=UTF-8",
+//           "x-parse-application-id": "dev"
+//         },
+//         "referrer": "http://127.0.0.1:4040/apps/DevServer/api_console/rest",
+//         "referrerPolicy": "no-referrer-when-downgrade",
+//         "body": body,
+//         "method": "PUT",
+//         "mode": "cors",
+//         "credentials": "omit"
+//       });
+//       let result = await response?.json()
+//       return result?.objectId
+// }
+
+
+
+// async function creatquestions(questionsInfo){
+//     let body = JSON.stringify(questionsInfo)
+//     let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Questions", {
+//   "headers": {
+//     "accept": "*/*",
+//     "accept-language": "zh-CN,zh;q=0.9",
+//     "content-type": "text/plain;charset=UTF-8",
+//     "x-parse-application-id": "dev"
+//   },
+//   "referrer": "http://127.0.0.1:4040/apps/DevServer/api_console/rest",
+//   "referrerPolicy": "no-referrer-when-downgrade",
+//   "body": body,
+//   "method": "POST",
+//   "mode": "cors",
+//   "credentials": "omit"
+// });
+// let result = await response?.json()
+// return result?.objectId
+// }
+
+// async function getquestions(){
+// let response = await fetch("http://dev.fmode.cn:1337/parse/classes/Questions?", {
+//     "headers": {
+//       "accept": "*/*",
+//       "accept-language": "zh-CN,zh;q=0.9",
+//       "x-parse-application-id": "dev"
+//     },
+//     "referrer": "http://127.0.0.1:4040/apps/DevServer/api_console/rest",
+//     "referrerPolicy": "no-referrer-when-downgrade",
+//     "body": null,
+//     "method": "GET",
+//     "mode": "cors",
+//     "credentials": "omit"
+//   });
+// let json = await response?.json();
+
+// return json?.results || []
+// }