Kaynağa Gözat

随访管理

ZTT 1 yıl önce
ebeveyn
işleme
179a7fc5a1
30 değiştirilmiş dosya ile 1986 ekleme ve 313 silme
  1. 11 17
      miniprogram/app.json
  2. 4 1
      miniprogram/module/chats/components/guide/guide.ts
  3. 14 0
      miniprogram/module/chats/components/message-again/message-again.json
  4. 269 0
      miniprogram/module/chats/components/message-again/message-again.scss
  5. 434 0
      miniprogram/module/chats/components/message-again/message-again.ts
  6. 169 0
      miniprogram/module/chats/components/message-again/message-again.wxml
  7. 10 2
      miniprogram/module/chats/components/message-analysis/message-analysis.ts
  8. 1 1
      miniprogram/module/chats/components/message-analysis/message-analysis.wxml
  9. 11 0
      miniprogram/module/chats/components/message-follow/message-follow.json
  10. 10 0
      miniprogram/module/chats/components/message-follow/message-follow.scss
  11. 30 0
      miniprogram/module/chats/components/message-follow/message-follow.ts
  12. 25 0
      miniprogram/module/chats/components/message-follow/message-follow.wxml
  13. 3 1
      miniprogram/module/chats/components/questionnaire/questionnaire.json
  14. 202 105
      miniprogram/module/chats/components/questionnaire/questionnaire.ts
  15. 3 1
      miniprogram/module/chats/components/questionnaire/questionnaire.wxml
  16. 127 36
      miniprogram/module/chats/pages/analysis/analysis.ts
  17. 2 1
      miniprogram/module/chats/pages/index/index.json
  18. 44 23
      miniprogram/module/chats/pages/index/index.ts
  19. 6 3
      miniprogram/module/chats/pages/index/index.wxml
  20. BIN
      miniprogram/module/follow/assets/icon/icon_report.png
  21. 13 0
      miniprogram/module/follow/pages/evaluation/report.json
  22. 106 0
      miniprogram/module/follow/pages/evaluation/report.scss
  23. 73 0
      miniprogram/module/follow/pages/evaluation/report.ts
  24. 85 0
      miniprogram/module/follow/pages/evaluation/report.wxml
  25. 3 0
      miniprogram/module/health/pages/analysis/analysis.ts
  26. 3 1
      miniprogram/pages/home/home.json
  27. 64 8
      miniprogram/pages/home/home.scss
  28. 227 113
      miniprogram/pages/home/home.ts
  29. 21 0
      miniprogram/pages/home/home.wxml
  30. 16 0
      miniprogram/pages/home/request.ts

+ 11 - 17
miniprogram/app.json

@@ -1,15 +1,10 @@
 {
-  "pages": [
-    "pages/home/home"
-  ],
+  "pages": ["pages/home/home"],
   "subpackages": [
     {
       "name": "chats",
       "root": "module/chats",
-      "pages": [
-        "pages/index/index",
-        "pages/analysis/analysis"
-      ]
+      "pages": ["pages/index/index", "pages/analysis/analysis"]
     },
     {
       "name": "health",
@@ -46,16 +41,17 @@
     {
       "name": "charts",
       "root": "module/charts",
-      "pages": [
-        "record-index/record-index"
-      ]
+      "pages": ["record-index/record-index"]
+    },
+    {
+      "name": "follow",
+      "root": "module/follow",
+      "pages": ["pages/evaluation/report"]
     }
   ],
   "preloadRule": {
     "pages/home/home": {
-      "packages": [
-        "chats"
-      ]
+      "packages": ["chats"]
     }
   },
   "window": {
@@ -84,12 +80,10 @@
     "t-message": "tdesign-miniprogram/message/message",
     "popup-privacy": "./components/popup-privacy/popup-privacy"
   },
-  "requiredPrivateInfos": [
-    "getFuzzyLocation"
-  ],
+  "requiredPrivateInfos": ["getFuzzyLocation"],
   "permission": {
     "scope.userFuzzyLocation": {
       "desc": "你的位置信息将用于小程序推荐"
     }
   }
-}
+}

+ 4 - 1
miniprogram/module/chats/components/guide/guide.ts

@@ -11,7 +11,10 @@ Component({
   },
   methods: {
     handleA() {
-      if (this.data.active) this.triggerEvent('next', { component: 'questionnaire', scroll: true });
+      if (this.data.active){
+         this.triggerEvent('next', { component: 'questionnaire', scroll: true});
+         this.triggerEvent('nextType', { MessageType:2 });
+      }
     },
     handleB() {
       if (this.data.active) wx.navigateTo({

+ 14 - 0
miniprogram/module/chats/components/message-again/message-again.json

@@ -0,0 +1,14 @@
+{
+  "renderer": "skyline",
+  "component": true,
+  "pureDataPattern": "^_",
+  "usingComponents": {
+    "t-popup": "tdesign-miniprogram/popup/popup",
+    "t-cell": "tdesign-miniprogram/cell/cell",
+    "t-icon": "tdesign-miniprogram/icon/icon",
+    "t-loading": "tdesign-miniprogram/loading/loading",
+    "user-avatar": "../../../../components/user-avatar/user-avatar",
+    "t-radio-group": "tdesign-miniprogram/radio-group/radio-group",
+    "t-radio": "tdesign-miniprogram/radio/radio"
+  }
+}

+ 269 - 0
miniprogram/module/chats/components/message-again/message-again.scss

@@ -0,0 +1,269 @@
+@import '../../../../themes/t.cell.scss';
+@import '../../common.scss';
+/* 页面容器 */
+.messages {
+  flex: 1;
+  overflow-y: auto;
+  padding: 10px;
+  box-sizing: border-box;
+}
+.chat-page {
+  position: relative;
+  height: 100vh;
+  overflow: hidden;
+}
+
+
+/* 输入容器基础样式 */
+.input-container {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  display: flex;
+  align-items: center;
+  padding: 20rpx;
+  background: #fff;
+  border-top: 1rpx solid #eee;
+  z-index: 100;
+  transform: translateY(0);
+  transition-property: transform;
+  transition-timing-function: ease-out;
+}
+
+/* 输入区域内部元素 */
+.input-container input {
+  flex: 1;
+  margin-right: 20rpx;
+  padding: 15rpx 20rpx;
+  border: 1rpx solid #ddd;
+  border-radius: 8rpx;
+}
+
+.input-container button {
+  padding: 0 30rpx;
+  height: 70rpx;
+  line-height: 70rpx;
+  background-color: #07c160;
+  color: white;
+  border-radius: 8rpx;
+}
+// 键盘的样式
+.header{
+  position: fixed;
+  width: 100%;
+  border-bottom: 1px solid #dddd;
+  text-align: center;
+  height: 40px;
+  line-height: 40px;
+}
+ 
+.message-list{
+  position: fixed;
+  width:100%;
+}
+.input-panel {
+  display: flex;
+  background: #dddddd;
+  height: 60px;
+  position: fixed;
+  width:100%;
+  padding:0px 10px;
+  align-items: center;
+  box-sizing: border-box;
+  // border: 1px solid red;
+}
+ 
+.input-panel input {
+  flex: 1;
+  width: 100%;
+  background: #ffffff;
+  height: 40px;
+  line-height: 50px;
+  box-sizing: border-box;
+  padding:0px 20rpx;
+  border-radius: 6rpx;
+  color: black;
+}
+ 
+.send-btn {
+  display: inline-block;
+  padding: 0px 10px;
+  color: #fff;
+  background: green;
+  border-radius: 3px;
+  line-height:40px;
+  margin-left:5px;
+}
+
+
+// ======================
+::v-deep .t-radio__title--disabled {
+  color: white !important;
+}
+.radio-card {
+  position: relative;
+  // margin: 20rpx 0 20rpx 20rpx;
+  border-radius: 12rpx;
+  overflow: hidden;
+  box-sizing: border-box;
+  // border: 3rpx solid var(--td-bg-color-container, #fff);
+}
+
+.card-active {
+  border-color: var(--td-brand-color, #0052d9);
+}
+
+.card-active::after {
+  content: '';
+  display: block;
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 0;
+  border-width: 28px 28px 28px 0;
+  border-style: solid;
+  border-color: var(--td-brand-color, #1B4F34) transparent transparent transparent;
+}
+
+.card__icons {
+  color: var(--td-bg-color-container, #fff);
+  position: absolute;
+  left: 1.5px;
+  top: 1.5px;
+  z-index: 1;
+}
+
+/* 横向布局 */
+.horizontal-box {
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+  flex-wrap: wrap;
+  margin: 20rpx 0 0rpx 0;
+}
+
+.horizontal-box .radio-card {
+  // flex: 0 0 calc(33.33% - 12rpx);
+  // margin: 0 0 24rpx 0;
+  width:46%;
+  margin: 0 0 20rpx 0;
+  text-align: center;
+}
+
+// .btn_box{
+//   display: flex;
+//   justify-content: space-between;
+//   align-items: center;
+//   width: 100%;
+//  .item1{
+//   width: 42%;
+//   background-color: #FFF2F3FF;
+//   color: #0052D9;
+//   border-radius: 10px;
+//   padding: 10px;
+//   text-align: center;
+//  }
+//  .item2{
+//   width: 42%;
+//   background-color: #0052D9;
+//   color: white;
+//   border-radius: 10px;
+//   padding: 10px;
+//   text-align: center;
+//  }
+//     .symptoms-container{
+//       display: flex;
+//       flex-wrap: wrap;
+//       .symptoms-box{
+//         padding: 10px;
+//       }
+//     }
+  
+// }
+.form-picker {
+  &__header {
+    display: flex;
+    align-items: center;
+    height: 116rpx;
+
+    .title {
+      flex: 1;
+      text-align: center;
+      font-weight: 600;
+      font-size: 36rpx;
+      color: var(--td-text-color-primary);
+    }
+
+    .btn {
+      font-size: 32rpx;
+      padding: 32rpx;
+
+      &--cancel {
+        color: var(--td-text-color-secondary);
+      }
+
+      &--confirm {
+        color: var(--primary-color);
+      }
+    }
+  }
+
+  &__content {
+    padding: 0 12px;
+    box-sizing: border-box;
+  }
+}
+
+/* module/chats/components/message-select/message-select.wxss */
+
+.card {
+  position: relative;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 4px;
+  font-size: 28rpx;
+  text-align: center;
+  border-radius: 12rpx;
+  overflow: hidden;
+  box-sizing: border-box;
+  background-color: var(--td-bg-color-secondarycontainer);
+  border: 1px solid var(--td-bg-color-container, #fff);
+
+  &--active {
+    border-color: var(--td-bg-color-container, #9ea1a5);
+
+    &::after {
+      content: '';
+      display: block;
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 0;
+      height: 0;
+      border-width: 28px 28px 28px 0;
+      border-style: solid;
+      border-color: var(--td-bg-color-container) transparent transparent transparent;
+      border: 14px solid var(--td-bg-color-container, #0052d9);
+      border-bottom-color: transparent;
+      border-right-color: transparent;
+    }
+  }
+
+  &--disabled {
+    opacity: 0.5;
+  }
+
+  &__icon {
+    color: var(--primary-color, #fff);
+    position: absolute;
+    left: 1.5px;
+    top: 1.5px;
+    z-index: 1;
+  }
+}
+
+.item.disabled {
+  opacity: 0.5;
+}

+ 434 - 0
miniprogram/module/chats/components/message-again/message-again.ts

@@ -0,0 +1,434 @@
+// module/chats/components/message-select/message-select.ts
+import { Message } from "tdesign-miniprogram";
+import { getTickleContext } from "../../../../core/behavior/tickle.behavior";
+import { Get, Post } from "../../../../lib/request/method";
+import Input from "../../../../miniprogram_npm/tdesign-miniprogram/input/input";
+interface Option {
+  id: string;
+  name: string;
+  checked?: boolean;
+  options: Option[] | null;
+}
+interface HandleEvent {
+  mark: {
+    type: "sub" | "options";
+    index: number;
+    item: Option;
+  };
+}
+const app = getApp();
+Component({
+  properties: {
+    payload: {
+      type: Object,
+      value: { title: "", multiple: false, options: [] },
+      result: "",
+    },
+    active: { type: Boolean, value: false },
+    workId: { type: Number, value: 0 },
+  },
+  data: {
+    // 键盘逻辑
+    inputBoxBottom: 0,
+    inputText: "",
+    messages: [],
+    scrollTop: 0, // 滚动位置
+    showrePlenish: false,
+    inputFocus: false,
+    // end
+    options: [],
+    subOptions: [] as Option[],
+    subMultiple: false,
+    itemHeight: 48,
+
+    result: "",
+    hasSelected: false,
+    required: false,
+    multiple: true,
+    value1: null,
+    radioList: [
+      {
+        id: "Y",
+        label: "有",
+        value: 0,
+      },
+      {
+        id: "N",
+        label: "没有",
+        value: 1,
+      },
+    ],
+    symptomResult: "",
+    btnDisabled: false,
+    followObj: {},
+    labelList: [],
+    symptomsList: [],
+    isHaveNewSyndrome: "",
+    isAnalysis: 0,
+    shows: false,
+  },
+  attached(options: any) {
+    this.setData({
+      isAnalysis: wx.getStorageSync("isAnalysis"),
+    });
+    if (wx.getSystemInfoSync().platform === "ios") {
+      this.setData({
+        inputBoxBottom: 10,
+      });
+    } else {
+      this.setData({
+        inputBoxBottom: 0,
+      });
+    }
+    // 键盘===========================
+    wx.onKeyboardHeightChange((res) => {
+      console.log(res, "res1111111111111");
+      const height = res.height;
+      if (height > 0) {
+        this.setData({
+          // 某些机型需要在此处也设置键盘高度
+          inputBoxBottom: height,
+        });
+      } else {
+        this.setData({
+          // 某些机型需要在此处也设置键盘高度
+          inputBoxBottom: 0,
+        });
+      }
+    });
+    console.log(this.data.inputBoxBottom, "刚进页面的高度");
+    // end======================
+    this.setData({
+      hasSelected: this.data.options
+        .filter((option) => !option.hide)
+        .some((option) => option.checked),
+    });
+    this.getContent();
+    this.getStatus();
+  },
+  observers: {
+    options(options: AnyArray) {
+      this.setData({
+        hasSelected: options
+          .filter((option) => !option.hide)
+          .some((option) => option.checked),
+      });
+    },
+    // 'messages':function(value: any) {
+    //   console.log(value, "messages11111");
+    //   if(value.length>0){
+
+    //   }
+    // },
+  },
+  methods: {
+    // 滚动到底部
+    // scrollToBottom() {
+    //   // 创建一个选择器获取消息容器高度
+    //   const query = wx.createSelectorQuery();
+    //   query.select(".messages").boundingClientRect();
+    //   query.exec((res) => {
+    //     if (res && res[0]) {
+    //       this.setData({
+    //         scrollTop: res[0].height,
+    //       });
+    //     }
+    //   });
+    // },
+    handleInput(e: any) {
+      // console.log(e, "输入框输入内容");
+      this.setData({ inputText: e.detail.value });
+    },
+    // 发送信息
+    send() {
+      const text = this.data.inputText.trim();
+      if (!text) {
+        wx.showToast({ title: "发送的信息不能为空", icon: "none" });
+        return;
+      }
+      const userMessage = {
+        id: Date.now().toString(),
+        content: text,
+        sender: "user",
+        timestamp: Date.now(),
+        status: "sending",
+      };
+      this.setData({
+        inputBoxBottom: 0,
+        messages: [...this.data.messages, userMessage],
+        inputText: "",
+      });
+      this.triggerEvent("boxBottom", {
+        inputBoxBottom: this.data.inputBoxBottom,
+      });
+      // 保持键盘打开状态
+      this.setData({ inputFocus: true });
+      if (this.data.messages.length === 2 && this.data.symptomResult === "有") {
+        this.setData({
+          showrePlenish: false,
+        });
+        this.triggerEvent("nextType", { MessageType: 2 });
+        this.triggerEvent("boxBottom", {
+          inputBoxBottom: this.data.inputBoxBottom - 50,
+        });
+      } else if (
+        this.data.messages.length === 1 &&
+        this.data.symptomResult === "没有"
+      ) {
+        this.setData({
+          showrePlenish: false,
+        });
+        this.triggerEvent("nextType", { MessageType: 2 });
+      }
+      // 滚动到底部
+      // this.scrollToBottom();
+    },
+    // 键盘聚焦
+    onInputFocus(e) {
+      this.setData({
+        inputFocus: false,
+        // 某些机型需要在此处也设置键盘高度
+        inputBoxBottom: e.detail.height || this.data.inputBoxBottom,
+      });
+      this.triggerEvent("boxBottom", {
+        inputBoxBottom: this.data.inputBoxBottom,
+      });
+    },
+    // 键盘失焦
+    onInputBlur() {
+      this.setData({
+        inputFocus: false,
+        inputBoxBottom: 0,
+      });
+      this.triggerEvent("boxBottom", {
+        inputBoxBottom: this.data.inputBoxBottom,
+      });
+    },
+    // end ============================
+    // 在字典中取症状的状态
+    async getStatus() {
+      const dict = await Get("/dict/getDicts", {
+        transform({ data }: any) {
+          return data;
+        },
+      });
+      // 查找出是随访病症的状态
+      let statusArr = dict.filter(
+        (item: any) => item.dictType === "followup_syndrome_change"
+      );
+      this.setData({
+        labelList: statusArr[0].items,
+      });
+    },
+    // 获取随访任务详情
+    async getContent() {
+      // 先从字典中获取状态
+      await this.getStatus();
+      let followArr: any = [];
+      try {
+        const res = await Post(
+          `/followupTaskManage/getFollowupTaskDetail/${this.data?.workId}`,
+          {},
+          {
+            transform({ data }: any) {
+              return data;
+            },
+          }
+        );
+        this.setData({ followObj: res });
+        // 处理数据
+        if (res.syndromeList.length > 0) {
+          res.syndromeList.forEach((syndrome: any, index: number) => {
+            followArr.push({
+              name: syndrome,
+              id: index + 1,
+              checked: false,
+              apiChecked: false,
+              options: [],
+            });
+            if (this.data.labelList.length > 0) {
+              this.data.labelList.forEach((label: any, lebelIdx: number) => {
+                followArr[index].options.push({
+                  name: label.dictLabel,
+                  id: lebelIdx + index + 1 + index,
+                  checked: false,
+                  apiChecked: false,
+                });
+              });
+            }
+          });
+        }
+        this.setData({ options: followArr });
+      } catch (error: any) {
+        wx.showToast({ title: error.errMsg, icon: "error" });
+      }
+    },
+    onChangeValue(e) {
+      this.setData({ value1: e.detail.value });
+      this.triggerEvent("boxBottom", {
+        inputBoxBottom: this.data.inputBoxBottom,
+      });
+      this.setData({
+        symptomResult: this.data.radioList.find(
+          (item) => item.value === e.detail.value
+        )?.label,
+        isHaveNewSyndrome: this.data.radioList.find(
+          (item) => item.value === e.detail.value
+        )?.id,
+      });
+      let followObj: any = {
+        isHaveNewSyndrome: this.data.isHaveNewSyndrome,
+        symptomList: this.data.symptomsList,
+      };
+      // console.log(this.data.isHaveNewSyndrome, "this.data.isHaveNewSyndrome");
+      this.setData({ btnDisabled: true });
+      wx.setStorageSync("followObj", followObj);
+      this.setData({
+        showrePlenish: true,
+      });
+    },
+    handleTop(event: HandleEvent) {
+      if (this.data.result) return;
+      const {
+        mark: { item },
+      } = event;
+      if (!item) return;
+      const index = this.data.options.findIndex(
+        (option) => option.id === item.id
+      );
+      const multiple = this.data.multiple;
+      const checked = !item.checked;
+      const options = this._handle(this.data.options, item, index, multiple);
+      this.setData({ options });
+      if (checked && !multiple) {
+        this.onSubmit();
+      }
+    },
+    handleSub(event: HandleEvent) {
+      const {
+        mark: { item },
+      } = event;
+      if (!item) return;
+      const index = this.data.subOptions.findIndex(
+        (option) => option.id === item.id
+      );
+      const multiple = this.data.subMultiple;
+      let checked;
+      this.data.subOptions.forEach((option: any, index: number) => {
+        if (option.id === item.id) {
+          checked = option.checked = true;
+        } else {
+          option.checked = false;
+        }
+      });
+      const subOptions = this._handle(
+        this.data.subOptions,
+        item,
+        index,
+        multiple
+      );
+      this.setData({ subOptions });
+
+      if (checked && !multiple) {
+        this.onConfirm();
+      }
+    },
+    _handle(
+      options: Option[],
+      item: Option,
+      index: number,
+      multiple?: boolean
+    ) {
+      const checked = !item.checked;
+      console.log(checked, multiple, "_handle");
+      if (checked) {
+        const fn = () => {
+          if (multiple) {
+            options[index].checked = checked;
+          } else {
+            options.forEach((option) => {
+              option.checked = option.id === item.id;
+            });
+          }
+          return options;
+        };
+        if (item.options?.filter((option) => !(<any>option)?.hide).length) {
+          this.setData({
+            subTitle: item.name,
+            subOptions: item.options,
+            subMultiple: true,
+          });
+          // console.log(this.data.subMultiple, "subOptions", item.css);
+          this.onCancel = () => {
+            this.setData({ subOptions: [] });
+          };
+          this.onConfirm = () => {
+            // console.log(this.data.subOptions, "subOptions", item.css);
+            if (!this.data.subOptions.some((option) => option.checked)) {
+              wx.showToast({ title: "请至少选择一项", icon: "error" });
+            } else {
+              const options = fn();
+              options[index].options = this.data.subOptions;
+              this.setData({ subOptions: [], options });
+            }
+          };
+        } else {
+          return fn();
+        }
+      } else {
+        options[index].checked = !item.checked;
+        if (item.options)
+          options[index].options = item.options.map((option) => {
+            if (!(<any>option)?.hide) option.checked = !item.checked;
+            return option;
+          });
+      }
+      return options;
+    },
+    onSubmit() {
+      if (this.data.result) return;
+      if (!this.data.hasSelected) {
+        wx.showToast({ title: "请至少选择一项", icon: "error" });
+      } else {
+        const result = this.data.options
+          .filter((item: any) => item?.checked && !item?.hide)
+          .map((option: any) => {
+            const sub = option.options
+              ?.filter((item: any) => item?.checked && !item?.hide)
+              .map((item: any) => item.name)
+              .join(", ");
+            return [option.name, sub].filter(Boolean).join(": ");
+          })
+          .join("; ");
+        this.setData({ result });
+
+        let symptomsList: any = [];
+        this.data.options.forEach((option: any) => {
+          const isCheck = option.options.every((item: any) => {
+            return !item.checked;
+          });
+          if (isCheck) {
+            symptomsList.push({ name: option.name, type: "" });
+          } else {
+            symptomsList.push({
+              name: option.name,
+              type:
+                option.options.find((item: any) => item.checked)?.name || "",
+            });
+          }
+        });
+        this.setData({ symptomsList });
+        console.log(symptomsList, "arr");
+        console.log(this.data.result, "result");
+        this.triggerEvent("next", { options: this.data.options });
+      }
+    },
+    onSkip() {
+      if (this.data.result || this.data.hasSelected) return;
+      if (!this.data.payload.required) {
+        this.setData({ result: "无变化" });
+        this.triggerEvent("next", { options: this.data.options });
+      }
+    },
+  },
+});

+ 169 - 0
miniprogram/module/chats/components/message-again/message-again.wxml

@@ -0,0 +1,169 @@
+
+<!--module/chats/components/message-again/message-again.wxml-->
+<wxs module="_">
+  module.exports.getClassName = function (option) {
+    if (!option) return '';
+    if (option.disabled) return 'card--disabled';
+    if (option.checked) return 'card--active';
+  }
+  module.exports.maxHeight = function (options, height, maxHeight) {
+    var rows = Math.ceil(options.filter(function (option) { return !option.hide }).length / 3);
+    return Math.min(rows * (height + 8), maxHeight || 350);
+  }
+  module.exports.subName = function (option) {
+    if (!option.options) return '';
+    var options = option.options
+      .filter(function (option) { return option.checked; })
+      .map(function (option) { return option.name; })
+    if (options.length) return ':' + options.join(' ');
+    return ''
+  }
+
+  module.exports.options = function (options) {
+    return options.filter(function (option) { return !option.hide })
+  }
+</wxs>
+<!--module/chats/components/message-select/message-select.wxml-->
+
+<view class="chat-card left">
+  <view class="chat-card__avatar ">
+    <image src="../../assets/robot.png" mode="aspectFill" />
+  </view>
+
+  <view class="chat-card__content">
+   <t-cell t-class="cell-border-gradient" title="您好,您于{{followObj.medicalTime}}在我院{{followObj.medicalDepartment}}因为{{followObj.diagnosis}}就诊。接下来,我们将对您进行一个随访,请依据您目前的实际情况回答。"></t-cell>
+  </view>
+</view>
+<view class="chat-card left">
+  <view class="chat-card__avatar ">
+    <image src="../../assets/robot.png" mode="aspectFill" />
+  </view>
+  <view class="chat-card__content">
+    <t-cell t-class="cell-border-gradient" title="请问您的情况是否有变化?" description="请点击症状进行选择"></t-cell>
+    <scroll-view class="options-wrapper" type="custom" scroll-y style="height: {{_.maxHeight(options, itemHeight)}}px;" mark:type="options" bind:tap="handleTop">
+      <grid-builder list="{{_.options(options)}}" cross-axis-count="3" cross-axis-gap="8" main-axis-gap="8" padding="{{[4,4,4,4]}}">
+        <view slot:item slot:index class="card {{_.getClassName(item)}}" style="height: {{itemHeight}}px;" mark:item="{{item}}">
+          <t-icon wx:if="{{item.checked}}" name="check" t-class="card__icon" ariaHidden="{{true}}" />
+          <text overflow="ellipsis" max-lines="2">{{item.name}}{{_.subName(item)}}</text>
+        </view>
+      </grid-builder>
+    </scroll-view>
+    <view wx:if="{{multiple || !required}}" class="chat-card__handle {{active ? '' : 'disabled'}}">
+      <view wx:if="{{!required}}" class="item {{hasSelected ? 'disabled': ''}}" bind:tap="onSkip">
+        <image src="../../assets/button-1.bg.png" mode="aspectFit" />
+        <view style="color: #d4d4d4;">无变化</view>
+      </view>
+      <view wx:if="{{multiple}}" class="item" bind:tap="onSubmit">
+        <image src="../../assets/button-1.bg.png" mode="aspectFit" />
+        <view>选好了</view>
+      </view>
+    </view>
+  </view>
+</view>
+
+<view class="chat-card right" wx:if="{{result}}">
+  <view class="chat-card__avatar ">
+    <user-avatar></user-avatar>
+  </view>
+  <view class="chat-card__content">
+    <t-cell title="{{result}}" bordered="{{false}}"></t-cell>
+  </view>
+  <t-loading wx:if="{{active}}" t-class="loading" theme="spinner" size="40rpx" class="wrapper" />
+</view>
+
+<view class="chat-card left"  wx:if="{{result}}"> 
+  <view class="chat-card__avatar ">
+    <image src="../../assets/robot.png" mode="aspectFill" />
+  </view>
+  <view class="chat-card__content">
+     <t-cell t-class="cell-border-gradient" title="请问有没有出现新的症状?"></t-cell>
+      <t-radio-group t-class="horizontal-box" value="{{value1}}" bind:change="onChangeValue" disabled="{{btnDisabled}}">
+  <view wx:for="{{radioList}}" wx:key="index" class="radio-card {{value1 == index ? 'card-active' : ''}}">
+    <t-icon wx:if="{{value1 == index}}" name="check" t-class="card__icon" ariaHidden="{{true}}" />
+    <t-radio value="{{index}}" label="{{item.label}}" icon="none" borderless  />
+  </view>
+</t-radio-group>
+     </view>
+  </view>
+
+
+
+<view class="chat-card right" wx:if="{{symptomResult}}">
+  <view class="chat-card__avatar ">
+    <user-avatar></user-avatar>
+  </view>
+  <view class="chat-card__content">
+    <t-cell title="{{symptomResult}}" bordered="{{false}}"></t-cell>
+  </view>
+  <t-loading wx:if="{{active}}" t-class="loading" theme="spinner" size="40rpx" class="wrapper" />
+</view>
+
+<view class="chat-card left" wx:if="{{symptomResult==='有'}}"> 
+  <view class="chat-card__avatar ">
+    <image src="../../assets/robot.png" mode="aspectFill" />
+  </view>
+  <view class="chat-card__content">
+     <t-cell t-class="cell-border-gradient" title="请描述新的症状?"></t-cell>
+     </view>
+  </view>
+
+    <view class="chat-card right" wx:if="{{messages[0].content && symptomResult==='有'}}">
+  <view class="chat-card__avatar ">
+    <user-avatar></user-avatar>
+  </view>
+  <view class="chat-card__content">
+    <t-cell title="{{messages[0].content}}" bordered="{{false}}"></t-cell>
+  </view>
+  <t-loading wx:if="{{active}}" t-class="loading" theme="spinner" size="40rpx" class="wrapper" />
+</view>
+
+
+<view class="chat-card left" wx:if="{{messages.length>0 || symptomResult==='没有' }}"> 
+  <view class="chat-card__avatar ">
+    <image src="../../assets/robot.png" mode="aspectFill" />
+  </view>
+  <view class="chat-card__content">
+     <t-cell t-class="cell-border-gradient" title="请问还有其他要补充的吗?"></t-cell>
+     </view>
+  </view>
+
+    <view class="chat-card right" wx:if="{{symptomResult==='有'?messages[1].content:false || symptomResult==='没有'?messages[0].content:false}}">
+  <view class="chat-card__avatar ">
+    <user-avatar></user-avatar>
+  </view>
+  <view class="chat-card__content">
+    <t-cell title="{{symptomResult==='有'?messages[1].content:messages[0].content}}" bordered="{{false}}"></t-cell>
+  </view>
+  <t-loading wx:if="{{active}}" t-class="loading" theme="spinner" size="40rpx" class="wrapper" />
+</view>
+
+
+
+
+<view class="input-panel" style="bottom:{{inputBoxBottom}}px;" wx:if="{{showrePlenish}}" >
+  <input bind:input="handleInput" value="{{inputText}}" adjust-position="{{false}}" placeholder="请输入"  bind:focus="onInputFocus" bind:blur="onInputBlur"
+   confirm-type="send" />
+  <view class="send-btn" bind:tap="send">发送</view>
+</view>
+
+
+<t-popup wx:if="{{subOptions.length}}" t-class="form-picker__inner" visible="{{true}}" bind:visible-change="onCancel" placement="bottom" close-on-overlay-click="{{false}}">
+  <view class="form-picker__header">
+    <view class="btn btn--cancel" aria-role="button" bind:tap="onCancel">取消</view>
+    <view class="title">{{subTitle}}</view>
+    <view wx:if="{{subMultiple}}" class="btn btn--confirm" aria-role="button" bind:tap="onConfirm">确定</view>
+  </view>
+  <view class="form-picker__content">
+    <scroll-view class="options-wrapper" type="custom" scroll-y style="height: {{_.maxHeight(subOptions, itemHeight)}}px;" mark:type="sub" bind:tap="handleSub">
+      <grid-builder list="{{_.options(subOptions)}}" cross-axis-count="3" cross-axis-gap="8" main-axis-gap="8" padding="{{[4,4,4,4]}}">
+        <view slot:item slot:index class="card {{_.getClassName(item)}}" style="height: {{itemHeight}}px;" mark:item="{{item}}">
+          <t-icon wx:if="{{item.checked}}" name="check" t-class="card__icon" ariaHidden="{{true}}" />
+          <text overflow="ellipsis" max-lines="2">{{item.name}}{{_.subName(item)}}</text>
+        </view>
+      </grid-builder>
+    </scroll-view>
+  </view>
+</t-popup>
+
+
+

+ 10 - 2
miniprogram/module/chats/components/message-analysis/message-analysis.ts

@@ -20,8 +20,10 @@ Component({
   properties: {
     payload: { type: Object, value: { title: '', description: '' } },
     active: { type: Boolean, value: false },
+    messageType: { type: Number, value: 0 },
   },
   data: {
+    isAnalysis: 0,
     examples: [
       { label: '舌面举例', src: '../../assets/tongue-1.png' },
       { label: '舌下举例', src: '../../assets/tongue-2.png' },
@@ -29,15 +31,21 @@ Component({
     ] as Gallery[],
     source: [] as Gallery[],
   },
-
+attached(){
+  this.setData({
+    isAnalysis: wx.getStorageSync("isAnalysis"),
+  });
+  
+},
   /**
    * 组件的方法列表
    */
   methods: {
     onConfirm() {
+   console.log(this.data.messageType,"this.data.messageType")
       if (this.data.source.length) return;
       wx.navigateTo({
-        url: '/module/chats/pages/analysis/analysis',
+        url: '/module/chats/pages/analysis/analysis?messageType=' + this.data.messageType,
         events: { update: (data: Result) => this._update(data) }
       });
     },

+ 1 - 1
miniprogram/module/chats/components/message-analysis/message-analysis.wxml

@@ -38,5 +38,5 @@
       </view>
     </view>
   </view>
-  <t-loading wx:if="{{active}}" t-class="loading" theme="spinner" size="40rpx" class="wrapper" />
+  <t-loading wx:if="{{active && isAnalysis===3}}" t-class="loading" theme="spinner" size="40rpx" class="wrapper" />
 </view>

+ 11 - 0
miniprogram/module/chats/components/message-follow/message-follow.json

@@ -0,0 +1,11 @@
+{
+  "renderer": "skyline",
+  "component": true,
+  "pureDataPattern": "^_",
+  "usingComponents": {
+    "t-cell": "tdesign-miniprogram/cell/cell",
+    "t-icon": "tdesign-miniprogram/icon/icon",
+    "t-loading": "tdesign-miniprogram/loading/loading",
+    "user-avatar": "../../../../components/user-avatar/user-avatar"
+  }
+}

+ 10 - 0
miniprogram/module/chats/components/message-follow/message-follow.scss

@@ -0,0 +1,10 @@
+@import '../../../../themes/t.cell.scss';
+@import '../../common.scss';
+
+/* module/chats/components/message-text/message-text.wxss */
+
+
+.chat-card__handle .item {
+  width: 280px * 0.5;
+  height: 52px * 0.5;
+}

+ 30 - 0
miniprogram/module/chats/components/message-follow/message-follow.ts

@@ -0,0 +1,30 @@
+// module/chats/components/message-text/message-text.ts
+Component({
+
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    payload: { type: Object, value: { title: '', loading: false } },
+    active: { type: Boolean, value: false },
+  },
+
+  /**
+   * 组件的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    seeReport(){
+      // const id = 1819;
+     const id = wx.getStorageSync("tonguefaceAnalysisReportId");
+     console.log("查看舌面像报告", id);
+     wx.navigateTo({ url: "/module/health/pages/analysis/analysis?id=" + id });
+   },
+  }
+})

+ 25 - 0
miniprogram/module/chats/components/message-follow/message-follow.wxml

@@ -0,0 +1,25 @@
+<!--module/chats/components/message-follow/message-follow.wxml-->
+<view class="chat-card left">
+  <view class="chat-card__avatar ">
+    <image src="../../assets/robot.png" mode="aspectFill" />
+  </view>
+
+  <view class="chat-card__content">
+   <t-cell t-class="cell-border-gradient" title="随访完成,感谢您的配合,祝您早日恢复!"></t-cell>
+  </view>
+</view>
+
+<view class="chat-card left">
+  <view class="chat-card__avatar ">
+    <image src="../../assets/robot.png" mode="aspectFill" />
+  </view>
+  <view class="chat-card__content">
+    <t-cell t-class="cell-border-gradient" title="查看舌面象分析报告">
+    </t-cell>
+    <view class="chat-card__handle">
+      <view class="item" bind:tap="seeReport">
+        <image src="../../assets/button-report.bg.png" mode="aspectFit" />
+      </view>
+    </view>
+  </view>
+</view>

+ 3 - 1
miniprogram/module/chats/components/questionnaire/questionnaire.json

@@ -10,6 +10,8 @@
     "message-select": "../message-select/message-select",
     "message-system": "../message-system/message-system",
     "message-text": "../message-text/message-text",
-    "message-report": "../message-report/message-report"
+    "message-report": "../message-report/message-report",
+    "message-again":"../message-again/message-again",
+    "message-follow":"../message-follow/message-follow"
   }
 }

+ 202 - 105
miniprogram/module/chats/components/questionnaire/questionnaire.ts

@@ -5,171 +5,271 @@ import { Post } from "../../../../lib/request/method";
 
 interface Message {
   id: string;
-  type: 'system' | 'analysis' | 'select' | 'text' | 'report';
+  type:
+    | "system"
+    | "analysis"
+    | "select"
+    | "text"
+    | "report"
+    | "again"
+    | "follow";
   payload: AnyObject;
 }
 
 interface HandleEvent {
-  target: { id: string; };
+  target: { id: string };
   detail: AnyObject;
-  type: 'next';
+  type: "next";
+}
+
+interface MessageType {
+  messageType: number;
 }
 
 Component({
   lifetimes: {
-    attached() { this._start(); }
+    attached: function () {
+      let isAnalysis: number;
+      isAnalysis = wx.getStorageSync("isAnalysis");
+      console.log("attached-isAnalysis", isAnalysis);
+      if (isAnalysis === 3) {
+        // 对话管家
+        this._start();
+      } else if (isAnalysis === 2) {
+        // 随访提醒
+        this.setData({
+          [`_next.classify`]: "",
+          [`_next.dialogId`]: "",
+          [`_next.questions`]: [],
+          _timestamp: Date.now(),
+        });
+        this._next();
+      }
+    },
   },
   properties: {
-
+    messageType: { type: Number, value: 0 },
+    workId: { type: Number, value: 0 },
   },
 
   /**
    * 组件的初始数据
    */
   data: {
+    inputBoxBottom: 0,
     messages: {} as Record<number, Message>,
-    lastId: '',
+    lastId: "",
     _next: {
       classify: "",
       dialogId: "",
-      questions: []
+      questions: [],
     } as AnyObject,
 
     _timestamp: Date.now(),
   },
   observers: {
-    'messages.**'(messages) {
+    "messages.**"(messages) {
       const message = Object.values(messages).pop() as Message;
       this.setData({ lastId: message?.id });
-    }
+    },
   },
   methods: {
+    nextType(event: MessageType) {
+      this.setData({ messageType: event.detail.MessageType });
+      this._next();
+    },
+    boxBottom(event: boxBottom) {
+      console.log(event, "监听页面高度event");
+      this.setData({ inputBoxBottom: event.detail.inputBoxBottom });
+      this.triggerEvent("boxBottom", {
+        inputBoxBottom: this.data.inputBoxBottom,
+      });
+      console.log(this.data.inputBoxBottom, "监听页面高度boxbottom");
+    },
     handle(event: HandleEvent) {
-      const index = event.target.id.split('.').pop() ?? 0;
-      console.log(index, event.target.id);
-
-
-      const questions = this.data._next.questions;
-      Object.assign(questions[index], event.detail);
-      this.setData({ '_next.questions': questions })
-      console.log(this.data._next);
-
-      this._next()
+      const isAnalysis = wx.getStorageSync("isAnalysis");
+      if (isAnalysis === 3) {
+        console.log(this.data._next, "handle", isAnalysis);
+        const index = event.target?.id.split(".").pop() ?? 0;
+        const questions = this.data._next.questions;
+        Object.assign(questions[index], event.detail);
+        this.setData({ "_next.questions": questions });
+        this._next();
+      } else {
+        this._createMessage({
+          id: 2,
+          type: "follow",
+          payload: { title: "" },
+        });
+      }
     },
     async _start() {
       try {
-        const count = await Post(`/patientInfoManage/rechargeUseDetail`, {}, {
-          transform({ data }: any) {
-            return data?.residuedCou
+        const count = await Post(
+          `/patientInfoManage/rechargeUseDetail`,
+          {},
+          {
+            transform({ data }: any) {
+              return data?.residuedCou;
+            },
           }
-        });
+        );
+        // console.log("count",count);
         if (count > 0) {
+          // if (count < 0) {
           this.setData({
-            [`_next.classify`]: '',
-            [`_next.dialogId`]: '',
+            [`_next.classify`]: "",
+            [`_next.dialogId`]: "",
             [`_next.questions`]: [],
             _timestamp: Date.now(),
-          })
+          });
           this._next();
         } else {
-          throw { errMsg: `您的健康分析次数已用完,请联系工作人员。` }
+          throw { errMsg: `您的健康分析次数已用完,请联系工作人员。` };
         }
       } catch (error) {
         this._createMessage({
-          id: `system-start`, type: 'system',
-          payload: { date: Date.now(), title: error.errMsg ?? `分析错误,请重试!`, }
+          id: `system-start`,
+          type: "system",
+          payload: {
+            date: Date.now(),
+            title: error.errMsg ?? `分析错误,请重试!`,
+          },
         });
         this._end();
       }
     },
     _end() {
       this.setData({
-        [`_next.classify`]: '',
-        [`_next.dialogId`]: '',
+        [`_next.classify`]: "",
+        [`_next.dialogId`]: "",
         [`_next.questions`]: [],
-      })
-      this.triggerEvent('next', { component: 'guide', scroll: true });
+      });
+      this.triggerEvent("next", { component: "guide", scroll: true });
     },
     async _next() {
-      if (this.data._next.classify === 'tongue') {
-        this._createMessage({
-          id: `tongue-loading.${Date.now()}`, type: 'text',
-          payload: { title: '分析中', loading: true }
-        });
-        this.triggerEvent('to');
+      let isAnalysis: number;
+      isAnalysis = wx.getStorageSync("isAnalysis");
+      if (isAnalysis === 3) {
+        // 对话管家
+        if (this.data._next.classify === "tongue") {
+          this._createMessage({
+            id: `tongue-loading.${Date.now()}`,
+            type: "text",
+            payload: { title: "分析中", loading: true },
+          });
+          this.triggerEvent("to");
+        }
       }
       try {
-        const { data } = await Post(`/dialogueManage/dialog`, this.data._next);
-        data.nextQuestions?.forEach((question: any, index: number) => {
-          if (question.classify === 'tongue_result') {
-            this._updateMessage({
-              id: `${question.classify}.${question.id}.${index}`, type: 'text',
-              payload: { title: question.content }
-            })
-          } else {
-            if (question.css === 'tongue') {
-              this._createMessage({
-                id: `${question.classify}.${question.id}.${index}`, type: 'analysis',
-                payload: { title: question.title }
-              });
-            } else if (question.css === 'text') {
-              this._createMessage({
-                id: `${question.classify}.${question.id}.${index}`, type: 'text',
-                payload: { title: question.content }
-              });
-            } else if (['select', 'checkbox'].includes(question.css)) {
+        if (this.data.messageType === 1) {
+          this._createMessage({
+            id: 1,
+            type: "again",
+            payload: { title: "" },
+          });
+        } else {
+          const { data } = await Post(
+            `/dialogueManage/dialog`,
+            this.data._next
+          );
+          data.nextQuestions?.forEach((question: any, index: number) => {
+            if (isAnalysis === 2) {
+              // 随访
+              if (question.css === "tongue") {
+                console.log(question, "tonguetongue");
+                this._createMessage({
+                  id: `${question.classify}.${question.id}.${index}`,
+                  type: "analysis",
+                  payload: { title: question.title },
+                });
+              }
+            } else {
+              // 对话管家
+              if (question.classify === "tongue_result") {
+                this._updateMessage({
+                  id: `${question.classify}.${question.id}.${index}`,
+                  type: "text",
+                  payload: { title: question.content },
+                });
+              } else {
+                if (question.css === "tongue") {
+                  console.log(question, "tonguetongue");
+                  this._createMessage({
+                    id: `${question.classify}.${question.id}.${index}`,
+                    type: "analysis",
+                    payload: { title: question.title },
+                  });
+                } else if (question.css === "text") {
+                  this._createMessage({
+                    id: `${question.classify}.${question.id}.${index}`,
+                    type: "text",
+                    payload: { title: question.content },
+                  });
+                } else if (["select", "checkbox"].includes(question.css)) {
+                  this._createMessage({
+                    id: `${question.classify}.${question.id}.${index}`,
+                    type: "select",
+                    payload: {
+                      title: question.title,
+                      options: question.options.map((item: AnyObject) => {
+                        if (Array.isArray(item.options)) {
+                          item.options = item.options.map((item) => {
+                            return { ...item, hide: item.css === "hide" };
+                          });
+                        }
+                        return { ...item, hide: item.css === "hide" };
+                      }),
+                      multiple: question.css === "checkbox",
+                      required: question.required,
+                    },
+                  });
+                } else if (question.over) {
+                  return this._end();
+                }
+              }
+            }
+          });
+          // 对话管家
+          if (isAnalysis === 3) {
+            if (data.classify === "report") {
+              const diff = dayjs().diff(this.data._timestamp, "m");
               this._createMessage({
-                id: `${question.classify}.${question.id}.${index}`, type: 'select',
+                id: "report",
+                type: "report",
                 payload: {
-                  title: question.title,
-                  options: question.options.map((item: AnyObject) => {
-                    if (Array.isArray(item.options)) {
-                      item.options = item.options.map(item => {
-                        return { ...item, hide: item.css === 'hide' }
-                      })
-                    }
-                    return { ...item, hide: item.css === 'hide' }
-                  }),
-                  multiple: question.css === 'checkbox',
-                  required: question.required
-                }
-              })
-            } else if (question.over) {
-              return this._end();
+                  title: `本次问答已结束,历时${
+                    diff || 1
+                  }分钟,非常感谢您的配合!请查看您本次的健康评估情况。`,
+                  url: `/module/health/pages/report/report?id=${data.healthAnalysisReportId}`,
+                },
+              });
             }
+            if (data.over) return this._end();
+
+            this.setData({
+              [`_next.classify`]: data.classify,
+              [`_next.dialogId`]: data.dialogId,
+              [`_next.questions`]: data.nextQuestions,
+            });
+            this.triggerEvent("to");
           }
-        });
-        if (data.classify === 'report') {
-          const diff = dayjs().diff(this.data._timestamp, 'm');
-          this._createMessage({
-            id: 'report', type: 'report',
-            payload: {
-              title: `本次问答已结束,历时${diff || 1}分钟,非常感谢您的配合!请查看您本次的健康评估情况。`,
-              url: `/module/health/pages/report/report?id=${data.healthAnalysisReportId}`
-            }
-          })
         }
-        if (data.over) return this._end();
-
-        this.setData({
-          [`_next.classify`]: data.classify,
-          [`_next.dialogId`]: data.dialogId,
-          [`_next.questions`]: data.nextQuestions,
-        })
-        this.triggerEvent('to');
       } catch (error) {
-        if (this.data._next.classify === 'tongue') {
+        if (this.data._next.classify === "tongue") {
           this._updateMessage({
-            id: `tongue-error-${Date.now()}`, type: 'text',
-            payload: { title: error.errMsg ?? `图像检测失败,请重新拍摄上传`, }
+            id: `tongue-error-${Date.now()}`,
+            type: "text",
+            payload: { title: error.errMsg ?? `图像检测失败,请重新拍摄上传` },
           });
-          this.triggerEvent('to');
+          this.triggerEvent("to");
           setTimeout(() => this._start(), 20);
         } else {
           const date = Date.now();
           this._createMessage({
-            id: `system-${date}`, type: 'system',
-            payload: { date, title: error.errMsg ?? `分析错误,请重试!`, }
+            id: `system-${date}`,
+            type: "system",
+            payload: { date, title: error.errMsg ?? `分析错误,请重试!` },
           });
           this._end();
         }
@@ -182,10 +282,7 @@ Component({
       this.setData({
         [`messages.${index}`]: body,
         ...data,
-      })
-
-      console.log(this.data.messages);
-
+      });
     },
 
     _updateMessage(body: Message) {
@@ -193,7 +290,7 @@ Component({
       const index = Object.keys(messages).length;
       this.setData({
         [`messages.${index - 1}`]: body,
-      })
+      });
     },
-  }
-})
+  },
+});

+ 3 - 1
miniprogram/module/chats/components/questionnaire/questionnaire.wxml

@@ -8,7 +8,9 @@
 </wxs>
 <!--module/chats/components/questionnaire/questionnaire.wxml-->
 <block wx:for="{{messages}}" wx:key="id">
-  <message-analysis wx:if="{{_.show(item,'analysis')}}" active="{{_.active(lastId,item.id)}}" id="{{item.id}}" payload="{{item.payload}}" bind:next="handle" />
+  <message-again wx:if="{{_.show(item,'again')}}" bind:nextType="nextType" workId="{{workId}}" bind:boxBottom="boxBottom" />
+  <message-analysis wx:elif="{{_.show(item,'analysis')}}" active="{{_.active(lastId,item.id)}}" id="{{item.id}}" payload="{{item.payload}}" bind:next="handle" messageType="{{messageType}}" />
+  <message-follow wx:elif="{{_.show(item,'follow')}}" bind:nextType="nextType" workId="{{workId}}" bind:boxBottom="boxBottom" />
   <message-select wx:elif="{{_.show(item,'select')}}" active="{{_.active(lastId,item.id)}}" id="{{item.id}}" payload="{{item.payload}}" bind:next="handle" />
   <message-text wx:elif="{{_.show(item,'text')}}" active="{{_.active(lastId,item.id)}}" id="{{item.id}}" payload="{{item.payload}}" bind:next="handle" />
   <message-report wx:elif="{{_.show(item,'report')}}" active="{{_.active(lastId,item.id)}}" id="{{item.id}}" payload="{{item.payload}}" bind:next="handle" />

+ 127 - 36
miniprogram/module/chats/pages/analysis/analysis.ts

@@ -1,41 +1,78 @@
 import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
 import { upload } from "../../../../lib/request/upload";
+import { Post } from "../../../../lib/request/method";
 
 // module/chats/pages/analysis/analysis.ts
 
 Component({
   behaviors: [PageContainerBehavior],
   options: {},
-  properties: {},
+  properties: {
+    messageType: { type: Number, value: 0 },
+  },
   data: {
     uploadList: [
-      { target: 'tongueImgUrl', required: true, label: '舌面图', src: '../../assets/tongue-1.png' },
-      { target: 'tongueBackImgUrl', required: true, label: '舌下图', src: '../../assets/tongue-2.png' },
-      { target: 'faceImgUrl', required: false, label: '面部图', src: '../../assets/face-1.png' },
+      {
+        target: "tongueImgUrl",
+        required: true,
+        label: "舌面图",
+        src: "../../assets/tongue-1.png",
+      },
+      {
+        target: "tongueBackImgUrl",
+        required: true,
+        label: "舌下图",
+        src: "../../assets/tongue-2.png",
+      },
+      {
+        target: "faceImgUrl",
+        required: false,
+        label: "面部图",
+        src: "../../assets/face-1.png",
+      },
     ],
     thumbnail: [] as string[],
     original: [] as string[],
     status: [false, false, false],
     _queue: {} as AnyObject,
+    // 随访上传参数
+    activeObj: {},
+    followObj: {},
+    workId: 0,
+  },
+  attached() {
+    // 从存储中拿到之前的对话信息
+    this.setData({
+      followObj: wx.getStorageSync("followObj"),
+      workId: wx.getStorageSync("workId"),
+    });
   },
   methods: {
     handle(event: WechatMiniprogram.TouchEvent) {
       const { handle, index } = event.mark as AnyObject;
-      console.log(handle, index, handle === 'upload:delete', event.mark);
+      console.log(handle, index, handle === "upload:delete", event.mark);
       switch (handle) {
-        case 'preview':
+        case "preview":
           break;
-        case 'upload':
-          this._chooseMedia(index).then(src => src && this._uploadMedia(index, src))
+        case "upload":
+          this._chooseMedia(index).then(
+            (src) => src && this._uploadMedia(index, src)
+          );
           break;
-        case 'upload:delete':
+        case "upload:delete":
           this._deleteMedia(index);
           break;
       }
     },
     _chooseMedia(index: number) {
-      return wx.chooseMedia({ count: 1, mediaType: ['image'], sourceType: ['album', 'camera'], camera: 'front' })
-        .then(res => {
+      return wx
+        .chooseMedia({
+          count: 1,
+          mediaType: ["image"],
+          sourceType: ["album", "camera"],
+          camera: "front",
+        })
+        .then((res) => {
           const src = res.tempFiles[0].tempFilePath;
           this.setData({ [`thumbnail.${index}`]: src });
           return src;
@@ -44,29 +81,36 @@ Component({
     },
     _deleteMedia(index: number) {
       this.setData({
-        [`thumbnail.${index}`]: '',
-        [`original.${index}`]: '',
-      })
+        [`thumbnail.${index}`]: "",
+        [`original.${index}`]: "",
+      });
     },
     _uploadMedia(index: number, src?: string) {
       this.setData({ [`_queue.${index}`]: true });
       src ??= this.data.thumbnail[index];
       upload({
-        params: { name: 'file', file: src! },
-        transform({ data }) { return (<any>data).url; }
-      }).then(src => {
-        this.setData({ [`original.${index}`]: src })
-      }, (error) => {
-        wx.showToast({ title: error?.errMsg ?? '上传失败', icon: 'error' })
-        this.setData({
-          [`thumbnail.${index}`]: '',
-          [`original.${index}`]: '',
-        })
-      }).then(() => {
-        this.setData({ [`_queue.${index}`]: false });
+        params: { name: "file", file: src! },
+        transform({ data }) {
+          return (<any>data).url;
+        },
       })
+        .then(
+          (src) => {
+            this.setData({ [`original.${index}`]: src });
+          },
+          (error) => {
+            wx.showToast({ title: error?.errMsg ?? "上传失败", icon: "error" });
+            this.setData({
+              [`thumbnail.${index}`]: "",
+              [`original.${index}`]: "",
+            });
+          }
+        )
+        .then(() => {
+          this.setData({ [`_queue.${index}`]: false });
+        });
     },
-    onSubmit() {
+    async onSubmit() {
       const data = {
         thumbnail: [] as any,
         source: [] as any,
@@ -74,17 +118,64 @@ Component({
       for (let index = 0; index < this.data.uploadList.length; index++) {
         const item = this.data.uploadList[index];
         if (this.data._queue[index]) {
-          wx.showToast({ title: `请等待图片上传完毕`, icon: 'none' });
+          wx.showToast({ title: `请等待图片上传完毕`, icon: "none" });
           return;
         } else if (item.required && !this.data.original[index]) {
-          wx.showToast({ title: `请上传${item.label}`, icon: 'none' });
+          wx.showToast({ title: `请上传${item.label}`, icon: "none" });
           return;
         }
-        if (this.data.original[index]) data.source.push({ target: item.target, src: this.data.original[index], })
-        if (this.data.thumbnail[index]) data.thumbnail.push({ target: item.target, src: this.data.thumbnail[index], })
+        if (this.data.original[index])
+          data.source.push({
+            target: item.target,
+            src: this.data.original[index],
+          });
+        if (this.data.thumbnail[index])
+          data.thumbnail.push({
+            target: item.target,
+            src: this.data.thumbnail[index],
+          });
+      }
+      let imageObj: any = {
+        upImg: this.data.thumbnail[0],
+        downImg: this.data.thumbnail[1],
+        faceImg: this.data.thumbnail[2],
+      };
+      this.setData({
+        activeObj: { ...imageObj, ...this.data.followObj },
+      });
+      console.log({ ...this.data.activeObj }, "activeObj");
+      let isAnalysis: number;
+      if (this.data.messageType === 2) {
+        isAnalysis = wx.getStorageSync("isAnalysis");
+      }
+      console.log(this.data.messageType, "messageType", isAnalysis);
+      if (isAnalysis === 2) {
+        // 提交随访提醒
+        try {
+          const res = await Post(
+            `/followupTaskManage/updateFollowupTaskFillin/${this.data?.workId}`,
+            { ...this.data.activeObj },
+            {
+              transform({ data }: any) {
+                return data;
+              },
+            }
+          );
+          // 存储舌面象分析报告id,用于跳转页面时最后产生结果查看
+          wx.setStorageSync(
+            "tonguefaceAnalysisReportId",
+            res.tonguefaceAnalysisReportId
+          );
+          this.getOpenerEventChannel().emit("update", data);
+          wx.navigateBack();
+        } catch (error) {
+          wx.showToast({ title: error.errMsg, icon: "error" });
+        }
+      } else {
+        // 对话管家
+        this.getOpenerEventChannel().emit("update", data);
+        wx.navigateBack();
       }
-      this.getOpenerEventChannel().emit('update', data)
-      wx.navigateBack()
-    }
-  }
-})
+    },
+  },
+});

+ 2 - 1
miniprogram/module/chats/pages/index/index.json

@@ -3,6 +3,7 @@
   "component": true,
   "usingComponents": {
     "chat-guide": "../../components/guide/guide",
-    "chat-questionnaire": "../../components/questionnaire/questionnaire"
+    "chat-questionnaire": "../../components/questionnaire/questionnaire",
+    "message-again": "../../components/message-again/message-again"
   }
 }

+ 44 - 23
miniprogram/module/chats/pages/index/index.ts

@@ -6,17 +6,20 @@ interface ScrollIntoViewEvent {
   detail: string;
 }
 interface HandleEvent {
-  detail: { component: 'guide' | 'questionnaire', scroll?: boolean }
+  detail: { component: "guide" | "questionnaire"; scroll?: boolean };
 }
-interface Message extends Omit<HandleEvent['detail'], 'scroll'> {
+interface NextTypeEvent {
+  detail: { messageType: number };
+}
+interface Message extends Omit<HandleEvent["detail"], "scroll"> {
   id: string;
 }
 
 function getScrollcontext(this: any) {
   return this as {
-    scroll: WechatMiniprogram.ScrollViewContext,
+    scroll: WechatMiniprogram.ScrollViewContext;
     timer: number;
-  }
+  };
 }
 
 Component({
@@ -24,48 +27,66 @@ Component({
   lifetimes: {
     attached() {
       this.setData({
-        date: dayjs().format('MM-DD HH:mm:ss'),
-      })
-      const component = this.data.component as 'guide' | 'questionnaire'
+        date: dayjs().format("MM-DD HH:mm:ss"),
+      });
+      const component = this.data.component as "guide" | "questionnaire";
       this.handle({ detail: { component, scroll: true } });
+      console.log("id-index",this.data);
     },
     ready() {
-      wx.createSelectorQuery().select('#scrollview').node().exec((res) => {
-        getScrollcontext.call(this).scroll = res[0].node;
-      })
-    }
+      wx.createSelectorQuery()
+        .select("#scrollview")
+        .node()
+        .exec((res) => {
+          getScrollcontext.call(this).scroll = res[0].node;
+        });
+    },
   },
   properties: {
-    component: { type: String, value: 'guide' }
+    component: { type: String, value: "guide" },
+    messageType: { type: Number, value: 0 },
+    isShowGuide: { type: Boolean, value: false },
+    id: { type: Number, value: 0 },
   },
   data: {
-    date: '',
+    date: "",
     messages: {} as Record<number, Message>,
-    lastId: '',
+    lastId: "",
+    inputBoxBottom:0,
   },
   observers: {
-    'messages.**'(messages) {
+    "messages.**"(messages) {
       const message = Object.values(messages).pop() as Message;
       this.setData({ lastId: message?.id });
-    }
+    },
   },
   methods: {
+    boxBottom(event: boxBottom) {
+      console.log(event, "监听页面index高度event");
+      this.setData({ inputBoxBottom: event.detail.inputBoxBottom+60 });
+      console.log(this.data.inputBoxBottom, "监听页面index高度boxbottom");
+    },
+    nextType(event: NextTypeEvent) {
+      this.setData({ messageType: event.detail.MessageType });
+    },
     handle(event: HandleEvent) {
       const index = Object.keys(this.data.messages).length;
       this.setData({
         [`messages.${index}`]: <Message>{
-          id: `${this.is.replace(/\//g, '_')}-${index}`,
+          id: `${this.is.replace(/\//g, "_")}-${index}`,
           component: event.detail?.component,
-        }
+        },
       });
-      if (event.detail?.scroll) this.scrollIntoView()
+      if (event.detail?.scroll) this.scrollIntoView();
     },
     scrollIntoView(event?: ScrollIntoViewEvent) {
       clearTimeout(getScrollcontext.call(this).timer);
       const id = event?.detail ?? this.data.lastId;
       getScrollcontext.call(this).timer = setTimeout(() => {
-        getScrollcontext.call(this).scroll?.scrollIntoView(`#${id}`, { alignment: 'end' });
-      }, 300)
+        getScrollcontext
+          .call(this)
+          .scroll?.scrollIntoView(`#${id}`, { alignment: "end" });
+      }, 300);
     },
-  }
-})
+  },
+});

+ 6 - 3
miniprogram/module/chats/pages/index/index.wxml

@@ -8,13 +8,16 @@
 </wxs>
 <!--module/chats/pages/index/index.wxml-->
 <t-navbar title="对话管家" left-arrow />
-<scroll-view id="scrollview" class="page-scroll__container" style="{{containerStyle}}" type="list" scroll-y enhanced="{{true}}" enable-passive scroll-into-view="{{lastId}}" scroll-into-view-alignment="end">
+<scroll-view id="scrollview" class="page-scroll__container" type="list" scroll-y enhanced="{{true}}" enable-passive scroll-into-view="{{lastId}}" scroll-into-view-alignment="end" style="bottom:{{inputBoxBottom}}px;" >
   <view class="system-wrapper">
     <view class="date">{{date}}</view>
     <view class="title">对话管家 已进入聊天</view>
   </view>
+  
   <block wx:for="{{messages}}" wx:key="id">
-    <chat-guide wx:if="{{_.show(item, 'guide')}}" id="{{item.id}}" active="{{_.active(lastId, item.id)}}" bind:next="handle" bind:to="scrollIntoView" />
-    <chat-questionnaire wx:if="{{_.show(item, 'questionnaire')}}" id="{{item.id}}" active="{{_.active(lastId, item.id)}}" bind:next="handle" bind:to="scrollIntoView" />
+    <chat-guide wx:if="{{(_.show(item, 'guide') && isShowGuide)}}" id="{{item.id}}" active="{{_.active(lastId, item.id)}}" bind:next="handle" bind:to="scrollIntoView" bind:nextType="nextType" />
+    <chat-questionnaire wx:if="{{_.show(item, 'questionnaire') && messageType}}" id="{{item.id}}" active="{{_.active(lastId, item.id)}}" bind:next="handle" bind:to="scrollIntoView" bind:nextType="nextType" messageType="{{messageType}}" workId="{{id}}" bind:boxBottom="boxBottom" />
   </block>
+ 
+
 </scroll-view>

BIN
miniprogram/module/follow/assets/icon/icon_report.png


+ 13 - 0
miniprogram/module/follow/pages/evaluation/report.json

@@ -0,0 +1,13 @@
+{
+  "renderer": "skyline",
+  "navigationBarTextStyle": "white",
+  "navigationBarBackgroundColor": "#0f2226",
+  "backgroundColor": "#0f2226",
+  "backgroundColorContent": "#0f2226",
+  "backgroundColorTop": "#0f2226",
+  "backgroundColorBottom": "#0f2226",
+  "component": true,
+  "usingComponents": {
+    "t-icon": "tdesign-miniprogram/icon/icon"
+  }
+}

+ 106 - 0
miniprogram/module/follow/pages/evaluation/report.scss

@@ -0,0 +1,106 @@
+.page-container {
+  background-color: #f3f3f3;
+  padding-top: 10px;
+  height: calc(100vh - 44px);
+  box-sizing: border-box;
+  -webkit-overflow-scrolling: touch;
+  .follow-box {
+    display: flex;
+    align-items: center;
+    background-color: #fff;
+    padding: 10px 16px;
+    font-size: 16px;
+
+    .title {
+      color: #666;
+      min-width: 80px;
+      flex-shrink: 0;
+    }
+
+    .content {
+      color: #000000;
+      margin-left:7px;
+      flex: 1;
+      line-height: 1.5;
+      word-break: break-all;
+    }
+  }
+  .follow-record {
+    color: #000000;
+    font-size: 16px;
+    font-weight: bold;
+    margin: 10px 0px 10px 15px;
+  }
+  .time-box {
+    width: 100%;
+    height: 34px;
+    line-height: 34px;
+    color: #000000;
+    font-size: 14px;
+    background-color: #e4e6ff;
+    padding-left: 10px;
+    font-weight: bold;
+  }
+  .record-box {
+    background-color: #fff;
+    padding: 10px 16px;
+    border-radius: 8px;
+
+    .new-symptoms {
+      margin-bottom: 20px;
+    }
+
+    .questions {
+      margin-bottom: 10px;
+    }
+
+    .sym-center {
+      margin-top: 10px;
+      margin-bottom: 10px;
+    }
+
+    .symptoms {
+      margin-left: 20px;
+      display: flex !important;
+      .improved {
+        color: #909090;
+        font-size: 16px;
+        width: 80px;
+      }
+    }
+
+    .image-box {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: space-between;
+      margin-top: 20px;
+      margin-bottom: 10px;
+      .tongue__img {
+        width: 30%;
+        height: 100px;
+        object-fit: cover;
+        border-radius: 8px;
+        // border: 1px solid #000000;
+      }
+    }
+    .report-box {
+      width: 98%;
+      height: 40px;
+      margin: 0 auto;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: #d6e1f3;
+      border-radius: 8px;
+      font-size: 15px;
+      color: #1F457F;
+      font-weight: bold;
+      .icon-bg {
+        width: 20px;
+        height: 20px;
+        margin-right: 5px;
+      }
+    }
+  }
+}

+ 73 - 0
miniprogram/module/follow/pages/evaluation/report.ts

@@ -0,0 +1,73 @@
+import { Get } from "../../../../lib/request/method";
+
+Page({
+  onLoad(options: { id: number }) {
+    console.log("options", options);
+    if (options.id) {
+      this.getReport(options.id);
+    }
+  },
+  data: {
+    id: "",
+    tasks: [
+      // {
+      //   idisHaveNewSyndrome: "Y",
+      //   otherDesc: "其他情况备注其他情况备注",
+      //   improve: "好转、心慌",
+      //   worse: "尿频、口渴",
+      //   noChange: "头晕",
+      //   upImg:
+      //     "https://ts1.tc.mm.bing.net/th/id/R-C.2fc875e6db412ea3001859644782e86c?rik=OXSZZhqD4QszEg&riu=http%3a%2f%2fpic30.photophoto.cn%2f20140324%2f0034034401728510_b.jpg&ehk=Q46dXLrEabrJDvvcvRaoVNz036jAfl4H0B2d0g%2fQZmA%3d&risl=&pid=ImgRaw&r=0",
+      //   downImg:
+      //     "https://ts1.tc.mm.bing.net/th/id/R-C.2fc875e6db412ea3001859644782e86c?rik=OXSZZhqD4QszEg&riu=http%3a%2f%2fpic30.photophoto.cn%2f20140324%2f0034034401728510_b.jpg&ehk=Q46dXLrEabrJDvvcvRaoVNz036jAfl4H0B2d0g%2fQZmA%3d&risl=&pid=ImgRaw&r=0",
+      //   faceImg:
+      //     "https://ts1.tc.mm.bing.net/th/id/R-C.2fc875e6db412ea3001859644782e86c?rik=OXSZZhqD4QszEg&riu=http%3a%2f%2fpic30.photophoto.cn%2f20140324%2f0034034401728510_b.jpg&ehk=Q46dXLrEabrJDvvcvRaoVNz036jAfl4H0B2d0g%2fQZmA%3d&risl=&pid=ImgRaw&r=0",
+      // },
+      // {
+      //   idisHaveNewSyndrome: "Y",
+      //   otherDesc: "其他情况备注其他情况备注",
+      //   improve: "好转、心慌",
+      //   worse: "尿频、口渴",
+      //   noChange: "头晕",
+      //   upImg:
+      //     "https://ts1.tc.mm.bing.net/th/id/R-C.2fc875e6db412ea3001859644782e86c?rik=OXSZZhqD4QszEg&riu=http%3a%2f%2fpic30.photophoto.cn%2f20140324%2f0034034401728510_b.jpg&ehk=Q46dXLrEabrJDvvcvRaoVNz036jAfl4H0B2d0g%2fQZmA%3d&risl=&pid=ImgRaw&r=0",
+      //   downImg:
+      //     "https://ts1.tc.mm.bing.net/th/id/R-C.2fc875e6db412ea3001859644782e86c?rik=OXSZZhqD4QszEg&riu=http%3a%2f%2fpic30.photophoto.cn%2f20140324%2f0034034401728510_b.jpg&ehk=Q46dXLrEabrJDvvcvRaoVNz036jAfl4H0B2d0g%2fQZmA%3d&risl=&pid=ImgRaw&r=0",
+      //   faceImg:
+      //     "https://ts1.tc.mm.bing.net/th/id/R-C.2fc875e6db412ea3001859644782e86c?rik=OXSZZhqD4QszEg&riu=http%3a%2f%2fpic30.photophoto.cn%2f20140324%2f0034034401728510_b.jpg&ehk=Q46dXLrEabrJDvvcvRaoVNz036jAfl4H0B2d0g%2fQZmA%3d&risl=&pid=ImgRaw&r=0",
+      // },
+    ],
+    followDetail: {
+      // followupPlanName: "随访计划名字",
+      // evaluateTime: "2024-10-06",
+      // evaluateBy: "张医生",
+      // evaluate: {
+      //   evaluateSituation: "好转",
+      //   evaluateDesc: "评估备注评估备注评估备注评估备注评估备注评估备注",
+      //   evaluateDeal: "复诊",
+      // },
+    },
+  },
+  async getReport(id: number) {
+    let list = await Get("/followupTaskManage/getFollowupTaskGroupDetailById", {
+      params: {
+        id,
+      },
+      transform({ data }: AnyObject) {
+        return data;
+      },
+    });
+    // console.log("list", list);
+    this.setData({
+      tasks: list.tasks,
+      followDetail: list,
+    });
+    // console.log("this.data", this.data);
+  },
+  goSeeFaceReport(e: any) {
+    // const id = 1819;
+    const id = e.currentTarget.dataset.id;
+    console.log("查看舌面像报告", id);
+    wx.navigateTo({ url: "/module/health/pages/analysis/analysis?id=" + id });
+  },
+});

+ 85 - 0
miniprogram/module/follow/pages/evaluation/report.wxml

@@ -0,0 +1,85 @@
+<t-navbar title="随访评估报告" left-arrow />
+<scroll-view class="page-container" scroll-y>
+ 
+ <view>
+    <view class="follow-box" style="padding-top:20px">
+      <view class="title">随访计划:</view>
+      <view class="content">{{followDetail.followupPlanName}}</view>
+    </view>
+    
+    <view class="follow-box">
+      <view class="title">评估结果:</view>
+      <view class="content">{{followDetail.evaluate.evaluateDeal==='1'?'复诊':followDetail.evaluate.evaluateDeal==='2'?'中医调养':''}}</view>
+    </view>
+
+ <view class="follow-box">
+      <view class="title">疾病专归:</view>
+      <view class="content">{{followDetail.evaluate.evaluateSituation==='1'?'痊愈':followDetail.evaluate.evaluateSituation==='2'?'好转':followDetail.evaluate.evaluateSituation==='3'?'无变化':followDetail.evaluate.evaluateSituation==='4'?'恶化':''}}</view>
+    </view>
+    <view class="follow-box">
+      <view class="title">评估备注:</view>
+      <view class="content">{{followDetail.evaluate.evaluateDesc}}</view>
+    </view>
+    <view class="follow-box">
+      <view class="title">评估医生:</view>
+      <view class="content">{{followDetail.evaluateBy}}</view>
+    </view>
+    <view class="follow-box" style="padding-bottom:20px">
+      <view class="title">评估日期:</view>
+      <view class="content">{{followDetail.evaluateTime}}</view>
+    </view>
+    </view>
+
+
+ <view class="follow-record">随访记录</view>
+
+  <block wx:for="{{tasks}}" wx:key="id" wx:for-item="task">
+    <view style="margin-bottom:16px">
+      <view class="time-box">{{task.arrangeTime}}</view>
+      <view class="record-box">
+        <view class="new-symptoms">
+          <view class="questions">1、请问您的症状是否已经好转?</view>
+          <view style="margin-top:10px">
+            <view class="symptoms">
+              <view class="improved">好转:</view>
+              <view>{{task.fillin?task.improve:'无'}}</view>
+            </view>
+            <view class="symptoms sym-center">
+              <view class="improved">恶化:</view>
+              <view>{{task.worse?task.worse:'无'}}</view>
+            </view>
+            <view class="symptoms">
+              <view class="improved">无变化:</view>
+              <view>{{task.noChange?task.noChange:'无'}}</view>
+            </view>
+          </view>
+        </view>
+
+       <view class="new-symptoms">
+          <view>2、请问有没有出现新的症状?</view>
+          <view style="margin-left:20px;margin-top:10px">{{task.fillin.isHaveNewSyndrome==='Y'?'有':task.fillin.isHaveNewSyndrome==='N'?'没有':'无'}}</view>
+        </view>
+
+        <view class="new-symptoms">
+          <view>3、如果有其他情况吗,请留言?</view>
+          <view style="margin-left:20px;margin-top:10px">{{task.fillin.otherDesc?task.fillin.otherDesc:'用户暂无留言~'}}</view>
+        </view>
+        
+          <view class="image-box" wx:if="{{task.fiilin.upImg || task.fillin.downImg || task.fillin.faceImg}}">
+          <image class="tongue__img" src="{{task.fiilin.upImg}}" mode="aspectFit" />
+          <image class="tongue__img" src="{{task.fillin.downImg}}" mode="aspectFit" />
+          <image class="tongue__img" src="{{task.fillin.faceImg}}" mode="aspectFit" />
+        </view>
+
+      <view class="report-box" wx:if="{{task.tonguefaceAnalysisReportId}}">
+          <image class="icon-bg" src="../../assets/icon/icon_report.png"  />
+          <view bind:tap="goSeeFaceReport" data-id="{{task.tonguefaceAnalysisReportId}}">查看舌面象分析报告</view>
+        </view>
+
+         
+
+      </view>
+    </view>
+  </block>
+  
+</scroll-view>

+ 3 - 0
miniprogram/module/health/pages/analysis/analysis.ts

@@ -19,10 +19,13 @@ Page({
     dataset: null as unknown as AnyObject,
   },
   onLoad(query: any) {
+    console.log(query,"query1111")
     this._load(query);
   },
 
   async _load(query: Record<'id' | 'scene', string>) {
+    console.log(query,"111");
+    
     wx.showLoading({ title: '加载中' });
     try {
       const { tongue, face, ...dataset } = await healthAnalysisMethod(query);

+ 3 - 1
miniprogram/pages/home/home.json

@@ -8,7 +8,9 @@
     "form-button": "../../components/button/button",
     "body-model": "./body-model/body-model",
     "report-health-scheme": "../../module/health/components/report-health-scheme/report-health-scheme",
-    "science-card": "../../module/article/components/science-card/science-card"
+    "science-card": "../../module/article/components/science-card/science-card",
+    "t-popup": "tdesign-miniprogram/popup/popup"
+
   },
   "componentPlaceholder": {
     "report-health-scheme": "view",

+ 64 - 8
miniprogram/pages/home/home.scss

@@ -2,7 +2,11 @@
 @import "../../themes/draggable-sheet.scss";
 @import "../../themes/t.cell.scss";
 @import "../../themes/card.scss";
-
+.scroll_live{
+  width: 100%;
+  height: 45vh;
+  overflow-y: scroll;
+}
 .container-bg-image {
   position: absolute;
   top: 0;
@@ -10,6 +14,13 @@
   width: 100%;
   height: 100%;
 }
+.block {
+  padding: 50px;
+  background: white;
+}
+.block-box {
+  display: flex;
+}
 
 /* pages/home/home.wxss */
 
@@ -88,12 +99,11 @@ $scale: 0.5;
     }
   }
 
-  .tool+.tool {
+  .tool + .tool {
     margin-left: 8px;
   }
 }
 
-
 .banner-wrapper {
   padding-top: 12px;
 
@@ -109,15 +119,13 @@ $scale: 0.5;
 }
 
 .draggable-sheet-wrapper {
-
   .bottom-wrapper {
     display: flex;
     justify-content: center;
     padding: 6px 0 24px;
   }
 
-
-  .row+.row {
+  .row + .row {
     margin-top: 8px;
   }
 
@@ -173,6 +181,54 @@ $scale: 0.5;
     flex-direction: row;
     align-items: center;
     font-size: 16px;
-    color: #37B473;
+    color: #37b473;
   }
-}
+}
+.popup-container {
+  position: relative;
+  width: 70vw;
+  height: 45vh;
+  background: white;
+  padding: 20rpx 30rpx;
+  border-radius: 20rpx;
+}
+
+.popup-block {
+  background: white;
+  // padding: 20rpx 40rpx 40rpx 40rpx;
+  // border-radius: 16rpx;
+  overflow: hidden;
+  height: 45vh !important;
+}
+.close-btn {
+  position: absolute;
+  left: 50%;
+  margin-left: -32rpx;
+  bottom: calc(-1 * (48rpx + 64rpx));
+}
+.popup-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px 0;
+  border-bottom: 1px solid #f0f0f0;
+
+  &:last-child {
+    border-bottom: none;
+  }
+}
+
+.popup-text {
+  font-size: 16px;
+  color: #333;
+}
+
+.popup-action {
+  font-size: 14px;
+  color: #37b473;
+}
+.t-popup__close {
+  width: 20px !important;
+  height: 20px !important;
+  color: #000 !important;
+}

+ 227 - 113
miniprogram/pages/home/home.ts

@@ -1,61 +1,81 @@
 import PageContainerBehavior from "../../core/behavior/page-container.behavior";
-import { DraggableSheetBehavior, getDraggableSheetContext } from "../../core/behavior/draggableSheet.behavior";
+import {
+  DraggableSheetBehavior,
+  getDraggableSheetContext,
+} from "../../core/behavior/draggableSheet.behavior";
 import { login } from "../../lib/logic";
 import { useRouteQuery } from "../../utils/route-query";
 import { appUpdate } from "../../lib/wx/update";
 
-const { shared, Easing, timing } = wx.worklet
+const { shared, Easing, timing } = wx.worklet;
 const offset = shared(0);
 
-const menus = ['shareAppMessage', 'shareTimeline'];
+const menus = ["shareAppMessage", "shareTimeline"];
 
 // pages/home/home.ts
-import { getPatients, healthReportMethod, healthIndexMethod, getSolarTerms, getShortScienceList, getPatientDescription } from "./request";
-import { toCertificationPage } from "./router";
+import {
+  getPatients,
+  healthReportMethod,
+  healthIndexMethod,
+  getSolarTerms,
+  getShortScienceList,
+  getPatientDescription,
+  getNotDealLists,
+} from "./request";
+import { toCertificationPage, toChats } from "./router";
 import { useLocation } from "../../lib/use/use-location";
 
 Page({
   behaviors: [
     PageContainerBehavior,
-    DraggableSheetBehavior('.draggable-sheet-wrapper'),
+    DraggableSheetBehavior(".draggable-sheet-wrapper"),
   ],
+  
   onLoad(options) {
     appUpdate();
-
     const query = useRouteQuery(options.scene!);
-    if (query.ys) wx.setStorageSync('doctorId', query.ys);
+    if (query.ys) wx.setStorageSync("doctorId", query.ys);
 
     this.initFabAnimated();
   },
   onShow() {
     wx.showShareMenu({ withShareTicket: true, menus }).then();
     this.load();
+     // 获取未处理随访列表
+     this.getNotDealList();
   },
   onHide() {
     wx.hideShareMenu({ menus }).then();
-    offset.value = timing(0, { duration: 100, easing: (<any>Easing).linear }, () => { 'worklet' });
+    offset.value = timing(
+      0,
+      { duration: 100, easing: (<any>Easing).linear },
+      () => {
+        "worklet";
+      }
+    );
   },
   onShareAppMessage(opts): WechatMiniprogram.Page.ICustomShareContent {
-    console.log(opts.target)
+    console.log(opts.target);
     return {
       title: `健康为基,从容赏生活之美`,
       imageUrl: `https://wx.hzliuzhi.com/media/healthManager/wx/share.jpg`,
       path: `/pages/home/home`,
-    }
+    };
   },
   onShareTimeline() {
     return {
       title: `健康为基,从容赏生活之美`,
-    }
+    };
   },
   data: {
-    patients: [] as (App.Patient.Model & { isDefault: 'Y' | 'N' })[],
+    popupList: [] as AnyArray,
+    isShowPopup: false,
+    patients: [] as (App.Patient.Model & { isDefault: "Y" | "N" })[],
     patient: null as App.Patient.Model | null,
-    patientDescription: '',
-
-    healthId: '',
-    healthReport: { data: null, message: '' },
-    healthIndex: { data: [], message: '' },
+    patientDescription: "",
+    healthId: "",
+    healthReport: { data: null, message: "" },
+    healthIndex: { data: [], message: "" },
 
     position: {} as AnyObject,
 
@@ -68,194 +88,287 @@ Page({
 
     _loaded: false,
   },
+  onClose() {
+    this.setData({
+      isShowPopup: false,
+    });
+  },
+  getNotDealList() {
+    getNotDealLists().then((res) => {
+      if (res.length > 0) {
+        this.setData({
+          popupList: res,
+        });
+        this.setData({
+          isShowPopup: true,
+        });
+      }
+    });
+  },
+  onVisibleChange(e: { detail: { visible: any } }) {
+    this.setData({
+      isShowPopup: e.detail.visible,
+    });
+  },
+  // 诊疗随访提醒
+  goComplete(e: { currentTarget: { dataset: { page: string; id: number } } }) {
+    wx.setStorageSync("isAnalysis", 2);
+    let page = e.currentTarget.dataset.page;
+    let id = e.currentTarget.dataset.id;
+    console.log("page", page);
+    if (page === "/module/chats/pages/index/index") {
+      wx.setStorageSync("workId", id);
+      wx.navigateTo({
+        url: `${page}?component=questionnaire&messageType=1&id=${id}`,
+      });
+    } else {
+      console.log("home中的id", id);
+      // wx.navigateTo({ url: `${page}?id=${id}` });
+      wx.navigateTo({ url: `/module/follow/pages/evaluation/report?id=${id}` });
+    }
+  },
+  // 随访评估报告已出
+  goSeeFollowReport() {
+    wx.navigateTo({ url: "/module/follow/pages/evaluation/report" });
+  },
   async load(forceLogin = false) {
     try {
       await login(forceLogin);
-      wx.showLoading({ title: '加载中' });
+      wx.showLoading({ title: "加载中" });
       const { patient } = await getPatients(/*this.data.patientId*/);
       if (!patient) await toCertificationPage();
       else {
         this.setData({ patient });
         this.observerPatient(patient);
-      };
+      }
       wx.hideLoading();
     } catch (error) {
-      await wx.showModal({
-        title: `加载失败`,
-        content: `${error?.errMsg ?? error?.message ?? ''}`,
-        showCancel: false,
-        confirmText: `重新加载`
-      }).catch(() => { });
+      await wx
+        .showModal({
+          title: `加载失败`,
+          content: `${error?.errMsg ?? error?.message ?? ""}`,
+          showCancel: false,
+          confirmText: `重新加载`,
+        })
+        .catch(() => {});
       this.load(true);
       return;
     }
 
     if (!this.data._loaded) {
       this.loadScienceList();
-      useLocation().then((location) => { this.setData({ location }) }).catch(() => { });
-      getSolarTerms().then((solarTerms) => { this.setData({ solarTerms }) }).catch(() => { });
+      useLocation()
+        .then((location) => {
+          this.setData({ location });
+        })
+        .catch(() => {});
+      getSolarTerms()
+        .then((solarTerms) => {
+          this.setData({ solarTerms });
+        })
+        .catch(() => {});
       this.setData({ _loaded: true });
     }
   },
 
   async _getHealthReport() {
-    wx.showLoading({ title: '加载中' });
-    this.setData({ 'healthReport.loading': true, })
+    wx.showLoading({ title: "加载中" });
+    this.setData({ "healthReport.loading": true });
     try {
       const data = await healthReportMethod();
       this.setData({
-        'healthReport.data': data,
-        'healthReport.loading': false,
+        "healthReport.data": data,
+        "healthReport.loading": false,
         healthId: data?.healthAnalysisReportId,
       });
     } catch (error) {
       this.setData({
-        'healthReport.data': [],
-        'healthReport.loading': false,
-        'healthReport.message': error.errMsg,
-        healthId: '',
+        "healthReport.data": [],
+        "healthReport.loading": false,
+        "healthReport.message": error.errMsg,
+        healthId: "",
       });
     }
     wx.hideLoading();
   },
   async _getAbnormalHealthIndex() {
-    this.setData({ 'healthIndex.loading': true, })
+    this.setData({ "healthIndex.loading": true });
     try {
       const data = await healthIndexMethod();
       this.setData({
-        'healthIndex.data': data.map((item: AnyObject) => item.abnormalDesc).filter(Boolean),
-        'healthIndex.loading': false,
+        "healthIndex.data": data
+          .map((item: AnyObject) => item.abnormalDesc)
+          .filter(Boolean),
+        "healthIndex.loading": false,
       });
     } catch (error) {
       this.setData({
-        'healthIndex.data': [],
-        'healthIndex.loading': false,
-        'healthIndex.message': error.errMsg,
+        "healthIndex.data": [],
+        "healthIndex.loading": false,
+        "healthIndex.message": error.errMsg,
       });
     }
   },
   onBodyModel(event: WechatMiniprogram.TouchEvent) {
-    if (event.detail?.position === 'LB') { this.toReportPage(); }
-    else if (event.detail?.position === 'LT') {
+    if (event.detail?.position === "LB") {
+      this.toReportPage();
+    } else if (event.detail?.position === "LT") {
       const report = this.data.healthReport.data as unknown as AnyObject;
       this.setData({
         position: {
-          LT: ['willillState', 'willillDegree', 'willillSocial', 'willillFunction'].map(key => {
-            const title = report[`${key}Name`]
-            const description = report[`${key}Description`]
-            return title || description ? { title, description } : null
-          }).filter(Boolean)
+          LT: [
+            "willillState",
+            "willillDegree",
+            "willillSocial",
+            "willillFunction",
+          ]
+            .map((key) => {
+              const title = report[`${key}Name`];
+              const description = report[`${key}Description`];
+              return title || description ? { title, description } : null;
+            })
+            .filter(Boolean),
         },
       });
       this.showDraggableSheet();
-    }
-    else if (event.detail?.position === 'RT') {
+    } else if (event.detail?.position === "RT") {
       const report = this.data.healthReport.data as unknown as AnyObject;
-      const get = (key: string) => ({ [key]: report[key] })
+      const get = (key: string) => ({ [key]: report[key] });
       this.setData({
         position: {
           RT: {
-            ...get('constitutionGroupName'),
-            ...get('constitutionGroupDefinition'),
-            ...get('faceImg'),
-            ...get('faceAnalysisResult'),
-            ...get('tongueAnalysisResult'),
-            ...get('upImg'),
-            ...get('downImg'),
-          }
+            ...get("constitutionGroupName"),
+            ...get("constitutionGroupDefinition"),
+            ...get("faceImg"),
+            ...get("faceAnalysisResult"),
+            ...get("tongueAnalysisResult"),
+            ...get("upImg"),
+            ...get("downImg"),
+          },
         },
       });
       this.showDraggableSheet();
-    }
-    else if (event.detail?.position === 'RB') {
+    } else if (event.detail?.position === "RB") {
       const report = this.data.healthReport.data as unknown as AnyObject;
-      const get = (key: string) => ({ [key]: report[key] })
+      const get = (key: string) => ({ [key]: report[key] });
       this.setData({
         position: {
           RB: {
-            ...get('diagnoseSyndromeSummary'),
-            ...get('diagnoseSyndromes'),
-            ...get('factorItemSummary'),
-            ...get('factorItems'),
-          }
+            ...get("diagnoseSyndromeSummary"),
+            ...get("diagnoseSyndromes"),
+            ...get("factorItemSummary"),
+            ...get("factorItems"),
+          },
         },
       });
       this.showDraggableSheet();
-    }
-    else if (event.detail?.position === 'CT') {
+    } else if (event.detail?.position === "CT") {
       this.setData({
-        position: { CT: this.data.healthIndex.data.map((item, index) => `${index + 1}、${item}`) }
+        position: {
+          CT: this.data.healthIndex.data.map(
+            (item, index) => `${index + 1}、${item}`
+          ),
+        },
       });
       this.showDraggableSheet();
     }
   },
 
   initFabAnimated() {
-    (<any>this).applyAnimatedStyle('.fab-wrapper', () => {
-      'worklet'
+    (<any>this).applyAnimatedStyle(".fab-wrapper", () => {
+      "worklet";
       return { right: `${Math.min(offset.value, 36) - 36}px` };
     });
-    (<any>this).applyAnimatedStyle('.fab-1', () => {
-      'worklet'
+    (<any>this).applyAnimatedStyle(".fab-1", () => {
+      "worklet";
       return { transform: `translateY(${-offset.value}px)` };
     });
-    (<any>this).applyAnimatedStyle('.fab-2', () => {
-      'worklet'
-      return { transform: `translateX(${-offset.value}px) translateY(${-offset.value / 2}px)` };
+    (<any>this).applyAnimatedStyle(".fab-2", () => {
+      "worklet";
+      return {
+        transform: `translateX(${-offset.value}px) translateY(${
+          -offset.value / 2
+        }px)`,
+      };
     });
-    (<any>this).applyAnimatedStyle('.fab-3', () => {
-      'worklet'
-      return { transform: `translateX(${-offset.value}px) translateY(${offset.value / 2}px)` };
+    (<any>this).applyAnimatedStyle(".fab-3", () => {
+      "worklet";
+      return {
+        transform: `translateX(${-offset.value}px) translateY(${
+          offset.value / 2
+        }px)`,
+      };
     });
-    (<any>this).applyAnimatedStyle('.fab-4', () => {
-      'worklet'
+    (<any>this).applyAnimatedStyle(".fab-4", () => {
+      "worklet";
       return { transform: `translateY(${offset.value}px)` };
     });
   },
   onFabTap() {
     const value = Math.abs(offset.value - 72);
-    offset.value = timing(value, { duration: 500, easing: (<any>Easing).linear }, () => {
-      'worklet'
-      if (offset.value > 0) offset.value = 72
-    })
+    offset.value = timing(
+      value,
+      { duration: 500, easing: (<any>Easing).linear },
+      () => {
+        "worklet";
+        if (offset.value > 0) offset.value = 72;
+      }
+    );
   },
   async toChatsPage() {
     if (!this.data.patient?.patientId) {
       try {
         await this.load();
       } catch (error) {
-        wx.showModal({ title: '出错了', content: error?.errMsg ?? error?.message ?? '错误,请重试', showCancel: false })
+        wx.showModal({
+          title: "出错了",
+          content: error?.errMsg ?? error?.message ?? "错误,请重试",
+          showCancel: false,
+        });
         return;
       }
     }
-    wx.navigateTo({ url: `/module/chats/pages/index/index` })
+    wx.setStorageSync("isAnalysis", 1);
+    const page = "/module/chats/pages/index/index";
+    wx.navigateTo({
+      url: `${page}?component=guide&isShowGuide=true`,
+    });
+    wx.setStorageSync("isAnalysis", 3);
+    // wx.navigateTo({ url: `/module/chats/pages/index/index` })
+    // toChats("guide");
   },
   toHealthPage() {
-    wx.navigateTo({ url: `/module/health/pages/home/home` })
+    wx.navigateTo({ url: `/module/health/pages/home/home` });
   },
   toDietTonicPage() {
-    wx.navigateTo({ url: `/module/article/pages/diet-list/diet-list?classify=tonic` })
+    wx.navigateTo({
+      url: `/module/article/pages/diet-list/diet-list?classify=tonic`,
+    });
   },
   toDietTeaPage() {
-    wx.navigateTo({ url: `/module/article/pages/diet-list/diet-list?classify=tea` })
+    wx.navigateTo({
+      url: `/module/article/pages/diet-list/diet-list?classify=tea`,
+    });
   },
   toSciencePage() {
-    wx.navigateTo({ url: `/module/article/pages/science-list/science-list` })
+    wx.navigateTo({ url: `/module/article/pages/science-list/science-list` });
   },
   toSchemePage() {
     const id = this.data.healthId;
-    if (id) wx.navigateTo({ url: `/module/health/pages/scheme/scheme?id=${id}` })
-    else wx.showToast({ title: '暂无调理方案', icon: 'none' });
+    if (id)
+      wx.navigateTo({ url: `/module/health/pages/scheme/scheme?id=${id}` });
+    else wx.showToast({ title: "暂无调理方案", icon: "none" });
   },
   toReportPage() {
     const id = this.data.healthId;
-    if (id) wx.navigateTo({ url: `/module/health/pages/report/report?id=${id}` })
-    else wx.showToast({ title: '暂无分析报告', icon: 'none' });
+    if (id)
+      wx.navigateTo({ url: `/module/health/pages/report/report?id=${id}` });
+    else wx.showToast({ title: "暂无分析报告", icon: "none" });
   },
   onDraggableSizeUpdate(e) {
-    'worklet'
+    "worklet";
     if (e.pixels < 1) {
-      wx.worklet.runOnJS(this.hideDraggableSheet.bind(this))()
+      wx.worklet.runOnJS(this.hideDraggableSheet.bind(this))();
     }
   },
   showDraggableSheet() {
@@ -264,7 +377,7 @@ Page({
       pixels: 600,
       animated: true,
       duration: 300,
-      easingFunction: 'ease'
+      easingFunction: "ease",
     });
     this.setData({ sheet: true });
   },
@@ -274,29 +387,30 @@ Page({
         size: 0,
         animated: true,
         duration: 300,
-        easingFunction: 'ease'
+        easingFunction: "ease",
       });
     }
-    this.setData({ position: {}, sheet: false })
+    this.setData({ position: {}, sheet: false });
   },
 
   async loadScienceList() {
     try {
       const { data } = await getShortScienceList();
-      this.setData({ scienceList: data })
-    } catch (error) {
-
-    }
+      this.setData({ scienceList: data });
+    } catch (error) {}
   },
 
-  observerPatient(model: { patientId: string, sex: '0' | '1' }) {
-    wx.setStorageSync('patientId', model.patientId);
+  observerPatient(model: { patientId: string; sex: "0" | "1" }) {
+    wx.setStorageSync("patientId", model.patientId);
     this._getHealthReport();
     this._getAbnormalHealthIndex();
-    const patientIcon = { 0: 'gender-male', 1: 'gender-female' }[model.sex];
-    const patientIconColor = { 0: '#0f40f5', 1: '#E560B3' }[model.sex];
-    this.setData({ patientIcon, patientIconColor })
+    const patientIcon = { 0: "gender-male", 1: "gender-female" }[model.sex];
+    const patientIconColor = { 0: "#0f40f5", 1: "#E560B3" }[model.sex];
 
-    getPatientDescription(model).then((patientDescription) => { this.setData({ patientDescription }) })
+    this.setData({ patientIcon, patientIconColor });
+
+    getPatientDescription(model).then((patientDescription) => {
+      this.setData({ patientDescription });
+    });
   },
-})
+});

+ 21 - 0
miniprogram/pages/home/home.wxml

@@ -126,4 +126,25 @@
       </view>
     </sticky-section>
   </scroll-view>
+
+
+  
+  <t-popup
+    visible="{{isShowPopup}}"
+    usingCustomNavbar
+    bind:visible-change="onVisibleChange"
+    placement="center"
+  >
+  <view class="popup-container">
+    <view class="popup-block">
+      <scroll-view class="scroll_live" scroll-y="{{true}}" show-scrollbar="{{false}}" enhanced="{{true}}" animation="{{animationData}}" >
+      <view class="popup-item" wx:for="{{popupList}}" wx:key="{{id}}">
+        <text class="popup-text">{{index+1}}.{{item.title}}</text>
+        <text class="popup-action" bind:tap="goComplete" data-page="{{item.page}}" data-id="{{item.pendingWorkId}}">{{item.button}}</text>
+      </view>
+      </scroll-view>
+    </view>
+    <t-icon t-class="close-btn" name="close-circle" size="64rpx" color="#fff" bind:tap="onClose" />
+    </view>
+  </t-popup>
 </draggable-sheet>

+ 16 - 0
miniprogram/pages/home/request.ts

@@ -1,5 +1,15 @@
 import { Get, Post } from "../../lib/request/method";
 
+export function getNotDealLists() {
+  return Post('/surplus/getPatientPendingWorks', {}, {
+    transform({ data }: AnyObject) {
+      return Array.isArray(data) ? data.map(item => ({
+        ...item,
+      })) : [];
+    }
+  })
+}
+
 export function getPatients(id?: string) {
   id ??= wx.getStorageSync('patientId')
   const transform = ({ data }: AnyObject) => {
@@ -64,4 +74,10 @@ export function getShortScienceList(page = 1, size = 3) {
       };
     }
   })
+}
+
+// 跳转聊天页面
+export function toChats(component: 'guide' | 'questionnaire') {
+  const navigate = wx.navigateTo({ url: `/module/chats/pages/index/index?component=${component}` })
+  return navigate;
 }