瀏覽代碼

update: tab2加了几个引用组件

xukang 4 月之前
父節點
當前提交
524eaf979e

+ 235 - 0
Git 分支操作.md

@@ -0,0 +1,235 @@
+# Git 分支操作
+
+```bash
+// 查看分支
+git branch:查看本地所有分支和当前所处分支
+git branch -r:查看远程分支(前提是进行了关联)
+git branch -a:查看所有分支(包括远程和本地分支)
+
+// 创建分支
+git branch branch_name:创建新分支
+git checkout branch_name:在本地切换到branch_name这个分支
+
+// 合并分支(若有多个分支,一般在master分支上合并其他分支)
+git merge branch_name
+
+// 删除分支(可以不用)
+git branch -d branch_name:删除本地仓库的branch_name分支
+git push -d origin branch_name:删除远程仓库的branch_name分支  // 不要用这个,误删就不好了
+
+// 关联远程仓库分支
+// branch_name最好不要是master分支,多人开发同时使用一个分支时,推送数据的时候容易冲突;branch_name 就用 xk 或者 xwy ,对应你们开发的分支
+// 本地分支的名字需要和远程仓库的分支名相对应(需在本地创建和远程仓库对应名字一样的分支)
+git push --set-upstream origin branch_name:设置本地的branch_name分支对应远程仓库的branch_name分支
+// 如果你们本地也有多个名字不同的分支,用下面这个;(branch_name2可以是master,这样就不用在本地创建和远程仓库名字一样的分支)
+git branch --set-upstream-to=origin/branch_name1 branch_name2:将远程的branch_name1分支与本地的branch_name2分支对应
+
+// 将本地数据推送到远程仓库
+git add .
+git commit -m "desc"
+git push // 不建议,若远程仓库和本地都只有一条命名相同的分支,则可以直接使用。其他情况不建议
+// 若远程仓库与本地所关联的分支命名不同 (branch_name对应所要推送到的远程仓库分支)
+git push origin HEAD:branch_name
+// 若远程仓库与本地所关联的分支命名相同
+git push origin HEAD
+
+// 拉取数据
+// 将远程仓库里的数据拉去到本地
+git pull:将远程仓库的当前分支与本地仓库的当前分支合并
+// 分支合并,多人多分支时使用,使用自己对应的分支
+git pull origin branch_name:将远程仓库的branch_name分支与本地仓库的当前分支合并
+git checkout -t origin/branch_name 将远程的branch_name分支拉取到本地
+```
+
+
+
+#### 常用 `git commit` 注释
+
+```bash
+feat: 新功能特性
+docs: 丰富文档
+fix: 修复
+update: 更新
+chrone: 杂项
+```
+
+
+
+<h2 style="color:red;">声明:在执行以下操作时,一定不要操作master分支。其他分支随意。</h2>
+
+#### 完整示例
+
+>   以下命令皆在 `git for windows` 终端中运行
+>
+>   以我个人相对应的 `cyx` 分支为例
+
+##### 新建git仓库并初始化
+
+```bash
+在路径(可随意):d/桌面/Git 下,新建了一个文件夹TFPower,以下所有命令在TFPower文件夹下执行
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git init
+Initialized empty Git repository in D:/桌面/Git/TFPower/.git/
+
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git config --global user.name cyx
+
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)
+$ git config --global user.email 2862576553@qq.com
+
+// 查看
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git config --global --list 
+user.name=cyx
+user.email=2862576553@qq.com
+credential.http://git.fmode.cn:3000.provider=generic
+```
+
+##### 关联远程仓库
+
+```bash
+// 关联远程仓库
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git remote add origin http://git.fmode.cn:3000/18779989085/202226701041.git
+
+
+
+// 新建的文件加下是没有master分支的(git branch,为空),须随便创建一个文件
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower-app (master)$ touch demo.txt
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower-app (master)$ git add .
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower-app (master)$ git commit -m "commit demo.txt"
+[master (root-commit) cd7df68] commit demo.txt
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ create mode 100644 demo.txt
+ 
+// 出现了
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower-app (master)$ git branch
+* master
+
+
+// 获取特定远程分支的更新
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git fetch
+
+// 关联分支
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git branch --set-upstream-to=origin/cyx master
+branch 'master' set up to track 'origin/cyx'.
+
+// 直接拉取错误,拒绝合并不相关的历史
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower-app (master)$ git pull
+fatal: refusing to merge unrelated histories
+
+//拉取分支最新版本(因为我已经在远程仓库创建好了),注意这里拉取的是cyx分支,跟之前关联的分支有关
+git pull --allow-unrelated-histories
+//即使关联其他分支,也可以拉去其他分支(master为例)
+git pull origin master --allow-unrelated-histories // 不建议,专心开发自己相对应的分支就好
+```
+
+##### 新建测试文件
+
+```bash
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ touch test.txt
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git status
+On branch master
+Your branch is up to date with 'origin/cyx'.
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+        test.txt
+
+nothing added to commit but untracked files present (use "git add" to track)
+
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git add .
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git commit -m "chrone: test the cyx branch"
+[master ce6f29f] chrone: test the cyx branch
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ create mode 100644 test.txt
+
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git branch
+* master
+
+// 直接 git push 会报错,因为我本地的分支为 master, 与云端上的不对应
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git push
+fatal: The upstream branch of your current branch does not match
+the name of your current branch.  To push to the upstream branch
+on the remote, use
+
+    git push origin HEAD:cyx
+
+To push to the branch of the same name on the remote, use
+
+    git push origin HEAD
+
+To choose either option permanently, see push.default in 'git help config'.
+
+To avoid automatically configuring an upstream branch when its name
+won't match the local branch, see option 'simple' of branch.autoSetupMerge
+in 'git help config'.
+
+// 成功,需使用这种方式推送数据到云端(`git push origin HEAD:branch_name`, 其中branch_name对应的是云端分支名称)
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git push origin HEAD:cyx
+Enumerating objects: 4, done.
+Counting objects: 100% (4/4), done.
+Delta compression using up to 16 threads
+Compressing objects: 100% (2/2), done.
+Writing objects: 100% (3/3), 271 bytes | 271.00 KiB/s, done.
+Total 3 (delta 1), reused 1 (delta 0), pack-reused 0 (from 0)
+To http://git.fmode.cn:3000/18779989085/202226701041.git
+   21a0091..ce6f29f  HEAD -> cyx
+```
+
+##### 修改测试文件
+
+在test.txt文件中添加如下内容(之前为空):
+
+```bash
+test
+a
+b
+c
+d
+e
+f
+g
+```
+
+```bash
+// 查看修改,修改了test.txt文件
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git status
+On branch master
+Your branch is up to date with 'origin/cyx'.
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git restore <file>..." to discard changes in working directory)
+        modified:   test.txt
+
+no changes added to commit (use "git add" and/or "git commit -a")
+
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git add .
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git commit -m "update: test the cyx branch & modified test.txt"
+[master e696cab] update: test the cyx branch & modified test.txt
+ 1 file changed, 8 insertions(+)
+ 
+ // 成功上传至远程仓库,且只能使用指令`git push origin HEAD:cyx`,直接`git push`会报错
+cyx@LAPTOP-FA84GREJ MINGW64 /d/桌面/Git/TFPower (master)$ git push origin HEAD:cyx
+Enumerating objects: 5, done.
+Counting objects: 100% (5/5), done.
+Delta compression using up to 16 threads
+Compressing objects: 100% (2/2), done.
+Writing objects: 100% (3/3), 286 bytes | 286.00 KiB/s, done.
+Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
+To http://git.fmode.cn:3000/18779989085/202226701041.git
+   ce6f29f..e696cab  HEAD -> cyx
+```
+
+### 结果
+
+#### cyx 分支
+
+![image-20241209183428577](C:\Users\cyx\AppData\Roaming\Typora\typora-user-images\image-20241209183428577.png)
+
+#### xk分支
+
+![image-20241209183616378](C:\Users\cyx\AppData\Roaming\Typora\typora-user-images\image-20241209183616378.png)
+
+#### master分支
+
+![image-20241209183451118](C:\Users\cyx\AppData\Roaming\Typora\typora-user-images\image-20241209183451118.png)
+
+可见:只修改了cyx分支内容,其他分支内容不变,实现不同开发人员独立开发。

+ 9 - 0
newwisefitnessapp/src/app/tab2/tab2.page.html

@@ -47,4 +47,13 @@
   <h2>{{shareData.diagResult.desc}}</h2>
   <p>{{shareData.diagResult.content}}</p>
   }
+  <!-- 聊天页面 -->
+  <h1>页面:配置路由和参数的聊天页</h1>
+  <ion-button (click)="goChat()">开始页面聊天</ion-button>
+  <h1>组件:直接弹出的聊天组件</h1>
+  <ion-button (click)="openChat()">开始新聊天</ion-button>
+  <ion-button (click)="restoreChat('yHEHqMQDNv')">恢复会话</ion-button>
+  <h1>示例:门诊问诊的智能体示例(ChatPanel组件)</h1>
+  <ion-button (click)="openInquiry()">进入门诊</ion-button>
+
 </ion-content>

+ 104 - 2
newwisefitnessapp/src/app/tab2/tab2.page.ts

@@ -2,8 +2,9 @@ import { Component, OnInit } from '@angular/core';
 import { IonHeader, IonToolbar, IonTitle, IonContent, IonButton, IonIcon, ModalController, IonProgressBar } from '@ionic/angular/standalone';
 import { AgentTaskStep } from 'src/app/agent/agent.task';
 import { addIcons } from 'ionicons';
+import { Router } from '@angular/router';
 import { radioButtonOffOutline, reloadOutline, checkmarkCircleOutline, closeCircleOutline } from 'ionicons/icons';
-import { FmodeChatCompletion, ImagineWork, DalleOptions } from "fmode-ng";
+import { FmodeChatCompletion, ImagineWork, DalleOptions, ChatPanelOptions, FmodeChat, FmodeChatMessage, openChatPanelModal } from "fmode-ng";
 import { DecimalPipe } from '@angular/common';
 import { startTask } from '../agent/agent.start';
 import { TaskPoemPictureDesc } from '../agent/tasks/poem/poem-desc';
@@ -22,7 +23,8 @@ addIcons({ radioButtonOffOutline, reloadOutline, checkmarkCircleOutline, closeCi
 })
 export class Tab2Page {
   //使用model弹出框就需要一个构造器先声明
-  constructor(private modalCtrl: ModalController) {
+  constructor(private modalCtrl: ModalController,
+    private router: Router) {
 
 
   }
@@ -62,6 +64,106 @@ export class Tab2Page {
     // 开始执行任务
     startTask(InquireServiceTaskList)
   }
+  // 聊天页面
+  openInquiry() {
+    localStorage.setItem("company", "E4KpGvTEto")
+    let options: ChatPanelOptions = {
+      roleId: "2DXJkRsjXK",
+      onChatInit: (chat: FmodeChat) => {
+        console.log("onChatInit");
+        console.log("预设角色", chat.role);
+        chat.role.set("name", "晓晓");
+        chat.role.set("title", "全科医生");
+        chat.role.set("desc", "一名亲切和蔼的门诊全科主任医生,晓晓,年龄36岁");
+        chat.role.set("tags", ["全科", "门诊"]);
+        chat.role.set("avatar", "https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/aigc/imagine/Q4Zif7fTbK-0.png")
+        chat.role.set("prompt", `
+# 角色设定
+您是一名亲切和蔼的专业的全科医生,晓晓,年龄36岁,需要完成一次完整的门诊服务。
+
+# 对话环节
+0.导诊(根据用户基本情况,引导挂号合适的科室)
+1.预设的问询方式(感冒问呼吸、肚子疼叩诊)
+- 打招呼,以用户自述为主
+- 当信息充足时候,确认用户症状对应的科室,并进入下一个环节
+2.拓展的问询细节
+例如:用户反映呼吸不畅,拓展出:是否咳嗽;是否感觉痛或者痒等其他需要的问题。
+- 当问询细节补充完成后进入下一个环节
+3.初步的诊断结果,并且同时列出检查检验项目
+初步诊断:确定需要有哪些进一步检查
+检查检验:获取医学客观数据
+- 等待用户提交客观数据,进入下一阶段
+4.给出诊断方案并给出处方
+- 完成处方时,请在消息结尾附带: [完成]
+
+# 开始话语
+当您准备好了,可以以一个医生的身份,向来访的用户打招呼。`);
+      },
+      onMessage: (chat: FmodeChat, message: FmodeChatMessage) => {
+        console.log("onMessage", message)
+        let content: any = message?.content
+        if (typeof content == "string") {
+          if (content?.indexOf("[完成]") > -1) {
+            console.log("门诊已完成")
+          }
+        }
+      },
+      onChatSaved: (chat: FmodeChat) => {
+        // chat?.chatSession?.id 本次会话的 chatId
+        console.log("onChatSaved", chat, chat?.chatSession, chat?.chatSession?.id)
+      }
+    }
+    openChatPanelModal(this.modalCtrl, options)
+  }
+
+  openChat() {
+    let options: ChatPanelOptions = {
+      roleId: "2DXJkRsjXK",
+      onChatSaved: (chat: FmodeChat) => {
+        // chat?.chatSession?.id 本次会话的 chatId
+
+        console.log("onChatSaved", chat, chat?.chatSession, chat?.chatSession?.id)
+
+      },
+
+    }
+    openChatPanelModal(this.modalCtrl, options)
+  }
+
+  restoreChat(chatId: string) {
+    let options: ChatPanelOptions = {
+      roleId: "2DXJkRsjXK",
+      chatId: chatId
+    }
+    openChatPanelModal(this.modalCtrl, options)
+  }
+
+  goChat() {
+    this.router.navigateByUrl("/chat/session/role/2DXJkRsjXK")
+  }
+
+
+  // audioModalHeightPoint:number = 0.35;
+  // async startTalk(){
+  //   // 根据手机兼容性,适配组件弹出高度
+  //   let height = document.body.clientHeight || 960;
+  //   this.audioModalHeightPoint = Number((165/height).toFixed(2));
+
+  //   // 弹出组件
+  //   let modal:any
+  //   let chat:any
+  //   modal = await this.modalCtrl.create({
+  //     component:ModalAudioMessageComponent,
+  //     componentProps:{
+  //       chat:chat,
+  //       modal:modal,
+  //       onBreakPointSet:()=>{
+  //         modal?.setCurrentBreakpoint(this.audioModalHeightPoint)
+  //       }
+  //     }
+  //   })
+  //   modal.present();
+  // }
 
 
 }

+ 165 - 0
wisefitness-server/wisdom-server/lib/ncloud.js

@@ -0,0 +1,165 @@
+
+
+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

+ 97 - 0
wisefitness-server/wisdom-server/migration/data.js

@@ -0,0 +1,97 @@
+module.exports.DoctorList = [
+    {
+      "objectId": "doc001",
+      "name": "张伟",
+      "title": "主任医师",
+      "desc": "拥有20年内科临床经验,擅长心血管疾病的治疗",
+      "gender": "男",
+      "age": 45,
+      "specialty": "内科",
+      "qualifications": ["医学博士,内科专科医生"],
+      "depart": {
+        "objectId": "dept001"
+      }
+    },
+    {
+      "objectId": "doc002",
+      "avatar":"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/aigc/imagine/Q4Zif7fTbK-0.png",
+      "name": "李娜",
+      "title": "主任医师",
+      "desc": "外科领域专家,擅长微创手术",
+      "gender": "女",
+      "age": 50,
+      "specialty": "外科",
+      "qualifications": ["外科专科医生,硕士研究生"],
+      "depart": {
+        "objectId": "dept002"
+      }
+    },
+    {
+      "objectId": "doc003",
+      "name": "王芳",
+      "title": "主任医师",
+      "desc": "儿童健康专家,擅长儿童生长发育",
+      "gender": "女",
+      "age": 40,
+      "specialty": "儿科",
+      "qualifications": ["儿科专科医生,医学硕士"],
+      "depart": {
+        "objectId": "dept003"
+      }
+    },
+    {
+      "objectId": "doc004",
+      "name": "刘强",
+      "title": "主任医师",
+      "desc": "妇产科专家,专注于高危妊娠管理",
+      "gender": "男",
+      "age": 48,
+      "specialty": "妇产科",
+      "qualifications": ["妇产科专科医生,博士研究生"],
+      "depart": {
+        "objectId": "dept004"
+      }
+    },
+    {
+      "objectId": "doc005",
+      "name": "陈静",
+      "title": "主任医师",
+      "desc": "神经科专家,擅长癫痫和头痛的治疗",
+      "gender": "女",
+      "age": 42,
+      "specialty": "神经科",
+      "qualifications": ["神经科专科医生,医学博士"],
+      "depart": {
+        "objectId": "dept005"
+      }
+    }
+  ]
+
+module.exports.DepartList = [
+
+      {
+        "objectId": "dept001",
+        "name": "内科",
+        "desc": "负责内科疾病的诊断和治疗"
+      },
+      {
+        "objectId": "dept002",
+        "name": "外科",
+        "desc": "负责外科手术和相关疾病的治疗"
+      },
+      {
+        "objectId": "dept003",
+        "name": "儿科",
+        "desc": "专注于儿童疾病的预防和治疗"
+      },
+      {
+        "objectId": "dept004",
+        "name": "妇产科",
+        "desc": "负责女性生殖系统及相关疾病的治疗"
+      },
+      {
+        "objectId": "dept005",
+        "name": "神经科",
+        "desc": "专注于神经系统疾病的诊断和治疗"
+      }
+    ]

+ 58 - 0
wisefitness-server/wisdom-server/migration/import-data.js

@@ -0,0 +1,58 @@
+const { CloudQuery, CloudObject } = require("../lib/ncloud");
+const { DepartList, DoctorList } = require("./data");
+inportDapartAndDoctor()
+
+DataMap = {
+    Doctor:{},
+    Department:{}
+}
+
+async function inportDapartAndDoctor(){
+    // 导入科室数据
+    let departList = DepartList
+    for (let index = 0; index < departList.length; index++) {
+        let depart = departList[index];
+        depart = await importObject("Department",depart)
+    }
+    // 导入医生数据
+    let doctorList = DoctorList
+    for (let index = 0; index < doctorList.length; index++) {
+        let doctor = doctorList[index];
+        doctor = await importObject("Doctor",doctor)
+    }
+    // console.log(DataMap["Doctor"])
+}
+
+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=="depart"){
+                data[key] = DataMap?.["Department"]?.[srcId]?.toPointer();
+            }
+        }
+    })
+
+    // 若未添加,则创建新对象并保存
+    if(!importObj?.id){
+        importObj = new CloudObject(className)
+    }
+
+    // 保存或更新数据
+    data.srcId = srcId;
+    importObj.set(data);
+    importObj = await importObj.save();
+
+    DataMap[className][srcId] = importObj
+}