hsy há 1 mês atrás
pai
commit
4b3643d404
70 ficheiros alterados com 0 adições e 20188 exclusões
  1. 0 162
      src/views/healthManagement/components/AssessmentHistory.vue
  2. 0 175
      src/views/healthManagement/components/AutoCompleteStep.vue
  3. 0 330
      src/views/healthManagement/components/BacklogConfigList.vue
  4. 0 392
      src/views/healthManagement/components/CurrentMonthTodoItems.vue
  5. 0 423
      src/views/healthManagement/components/DataCalc.vue
  6. 0 45
      src/views/healthManagement/components/DataCalcTool.vue
  7. 0 288
      src/views/healthManagement/components/DialogBacklog copy 2.vue
  8. 0 187
      src/views/healthManagement/components/DialogBacklog copy.vue
  9. 0 551
      src/views/healthManagement/components/DialogBacklog.vue
  10. 0 417
      src/views/healthManagement/components/DialogBacklogCheckbox.vue
  11. 0 371
      src/views/healthManagement/components/DialogCurrentMonthBacklog.vue
  12. 0 147
      src/views/healthManagement/components/DialogEditTags.vue
  13. 0 230
      src/views/healthManagement/components/DialogHealthManageEvaluationHistory.vue
  14. 0 47
      src/views/healthManagement/components/DialogPreviewSuggest.vue
  15. 0 183
      src/views/healthManagement/components/DialogSelectIllness.vue
  16. 0 126
      src/views/healthManagement/components/DialogSetMatter.vue
  17. 0 148
      src/views/healthManagement/components/DiseaseAnalysis.vue
  18. 0 338
      src/views/healthManagement/components/DiseaseQA.vue
  19. 0 169
      src/views/healthManagement/components/DiseaseVisit.vue
  20. 0 17
      src/views/healthManagement/components/EvaluateCard.vue
  21. 0 75
      src/views/healthManagement/components/FollowUpData.vue
  22. 0 176
      src/views/healthManagement/components/HealthManagementPlan.vue
  23. 0 422
      src/views/healthManagement/components/HealthManagementPlanDetail.vue
  24. 0 438
      src/views/healthManagement/components/HorizontalContrast.vue
  25. 0 300
      src/views/healthManagement/components/IndicatorTrends.vue
  26. 0 73
      src/views/healthManagement/components/LastTimeContent.vue
  27. 0 505
      src/views/healthManagement/components/LatestUserDataAnalysis.vue
  28. 0 112
      src/views/healthManagement/components/ManagementPlan.vue
  29. 0 437
      src/views/healthManagement/components/ManagementPlanDetail.vue
  30. 0 145
      src/views/healthManagement/components/PlanArchives.vue
  31. 0 231
      src/views/healthManagement/components/PlanCheckData.vue
  32. 0 24
      src/views/healthManagement/components/PreviewSetItemTable.vue
  33. 0 119
      src/views/healthManagement/components/ProfileCard.vue
  34. 0 104
      src/views/healthManagement/components/ReturnVisitItem.vue
  35. 0 120
      src/views/healthManagement/components/RiskWarningReport.vue
  36. 0 158
      src/views/healthManagement/components/SetCheckItem.vue
  37. 0 104
      src/views/healthManagement/components/SetOtherItem.vue
  38. 0 216
      src/views/healthManagement/components/SetRetrun.vue
  39. 0 685
      src/views/healthManagement/components/SimpleQuestionItem.vue
  40. 0 126
      src/views/healthManagement/components/TableSetItem.vue
  41. 0 205
      src/views/healthManagement/components/TodoItemCheck.vue
  42. 0 298
      src/views/healthManagement/components/TodoItemFollowUp.vue
  43. 0 180
      src/views/healthManagement/components/TodoItemInspect.vue
  44. 0 197
      src/views/healthManagement/components/TodoItemMonitor.vue
  45. 0 155
      src/views/healthManagement/components/TodoItemOther.vue
  46. 0 209
      src/views/healthManagement/components/TodoItemReturnVisit.vue
  47. 0 239
      src/views/healthManagement/components/TrendOfRiskChange.vue
  48. 0 346
      src/views/healthManagement/components/UserDataAnalysis.vue
  49. 0 272
      src/views/healthManagement/components/UserDataAnalysisEvaluate.vue
  50. 0 1222
      src/views/healthManagement/components/customSurvey.vue
  51. 0 1284
      src/views/healthManagement/components/questionItem.vue
  52. 0 1029
      src/views/healthManagement/evaluate.vue
  53. 0 110
      src/views/healthManagement/healthPPT.vue
  54. 0 487
      src/views/healthManagement/healthPlan.vue
  55. 0 272
      src/views/healthManagement/healthPlan/AnalysisOfEtiology.vue
  56. 0 160
      src/views/healthManagement/healthPlan/DataCollection.vue
  57. 0 4
      src/views/healthManagement/healthPlan/FollowUpData.vue
  58. 0 199
      src/views/healthManagement/healthPlan/HealthArchivesModuleView.vue
  59. 0 91
      src/views/healthManagement/healthPlan/HealthCheckData.vue
  60. 0 158
      src/views/healthManagement/healthPlan/HealthPlanCheckData.vue
  61. 0 566
      src/views/healthManagement/healthPlan/HealthPortrait.vue
  62. 0 295
      src/views/healthManagement/healthPlan/IndividualInterventionProgram.vue
  63. 0 70
      src/views/healthManagement/healthPlan/LeftMenu.vue
  64. 0 87
      src/views/healthManagement/healthPlan/NextFeedbackSetting.vue
  65. 0 237
      src/views/healthManagement/healthPlan/SituationAssessment.vue
  66. 0 556
      src/views/healthManagement/managementHealthPlan.vue
  67. 0 685
      src/views/healthManagement/managementPlan.vue
  68. 0 169
      src/views/healthManagement/messageNotification.vue
  69. 0 463
      src/views/healthManagement/planDetail.vue
  70. 0 627
      src/views/healthManagement/todoList.vue

+ 0 - 162
src/views/healthManagement/components/AssessmentHistory.vue

@@ -1,162 +0,0 @@
-<template>
-  <div class="p-4">
-    <div v-if="props.list.length">
-      <div class="bg-white h-64 rounded shadow">
-        <Chart ref="chartRef" />
-      </div>
-      <div class="bg-white rounded shadow p-4 mt-4">
-        <el-timeline>
-          <el-timeline-item v-for="(item, index) in historyList" :key="index">
-            <div class="space-x-4">
-              <span class="text-gray-500 font-bold">
-                {{
-                  index == historyList.length - 1
-                    ? "-"
-                    : historyList[
-                        index - 1 > 0 ? index - 1 : 0
-                      ]?.nextTime?.split(" ")[0]
-                }}
-                至
-                {{ item.nextTime?.split(" ")[0] }}
-              </span>
-              <el-tag v-if="index != historyList.length - 1">{{
-                manageLevel[item.level]?.anotherName
-              }}</el-tag>
-            </div>
-            <div v-if="index !== historyList.length - 1">
-              <div>管理目标:</div>
-              <el-text size="small">{{
-                historyList[index + 1]?.target
-              }}</el-text>
-            </div>
-            <div class="mt-2">
-              <span>管理效果评价: </span> <span>{{ item.effect?.name }}</span>
-            </div>
-            <div>
-              <span>主要存在问题:</span>
-              <span v-if="item.focus || item?.focus?.length">
-                <el-tag class="ml-2" v-for="(pro, i) in item.focus" :key="i">{{
-                  pro
-                }}</el-tag>
-              </span>
-              <span v-else>-</span>
-            </div>
-
-            <div v-if="index !== historyList.length - 1">
-              <span>个性化健康建议:</span>
-              <span>{{ historyList[index + 1]?.advise }}</span>
-            </div>
-          </el-timeline-item>
-        </el-timeline>
-      </div>
-    </div>
-    <div v-else>
-      <el-empty description="暂无评估历史"></el-empty>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  ref,
-  reactive,
-  inject,
-  onActivated,
-  onMounted,
-  defineAsyncComponent,
-  defineProps,
-  nextTick,
-  defineExpose
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { manageLevel } from "@/enums/managementPlan.ts";
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-
-import { request, formateArchivesModuleValue, deepClone } from "@/utils";
-import Chart from "@/components/Chart.vue";
-
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const props = defineProps({
-  list: {
-    type: Array
-  }
-});
-const historyList = computed(() => {
-  let arr = props.list;
-  console.log(arr, "历史数据");
-  return arr;
-});
-const chartRef = ref();
-
-const list = ref([]);
-
-const init = async () => {
-  chartRef?.value?.setOption({
-    title: {
-      text: "管理效果趋势",
-      top: "10",
-      left: "10"
-    },
-    grid: {
-      left: "5%",
-      right: "5%",
-      bottom: "15%"
-    },
-    // tooltip: {
-    //   trigger: "axis",
-    //   showContent: true
-    // },
-    xAxis: {
-      type: "category",
-      data: props.list.map(v => v.createdAt?.split(" ")[0]).reverse()
-    },
-    yAxis: {
-      type: "value",
-      axisLine: { show: false },
-      axisTick: { show: false },
-      axisLabel: { show: false }
-    },
-    series: [
-      {
-        data: props.list.map(v => Number(v.effect["程度"])).reverse(),
-        type: "line",
-        label: {
-          show: true,
-          position: "top",
-          formatter: params => {
-            return props.list.find(v => v.effect["程度"] == params.value)
-              ?.effect?.name;
-          }
-        },
-        smooth: true
-      }
-    ]
-  });
-};
-watch(
-  props.list,
-  (n, o) => {
-    nextTick(() => {
-      setTimeout(init, 1000);
-    });
-  },
-  { deep: true, immediate: true }
-);
-onMounted(() => {
-  // init();
-});
-
-defineExpose({
-  initChart: () => {
-    nextTick(init);
-  }
-});
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 175
src/views/healthManagement/components/AutoCompleteStep.vue

@@ -1,175 +0,0 @@
-<template>
-  <!-- 步骤条 -->
-  <div class="h-[120px]">
-    <div class="box">
-      <div class="progress">
-        <div class="bar">
-          <div
-            class="bar__fill"
-            :style="`width: ${(100 / (stepList.length - 1)) * curStep}%`"
-          ></div>
-        </div>
-        <div
-          v-for="(item, index) in stepList"
-          :key="index"
-          class="point"
-          :class="{
-            'point--active': item.value == curStep,
-            'point--complete': item.value < curStep
-          }"
-        >
-          <div class="h-6 w-6 bg-white rounded-full">
-            <Loading v-if="item.value == curStep" class="animate-spin" />
-            <CircleCheckFilled v-else-if="item.value < curStep" />
-            <div v-else><MoreFilled /></div>
-          </div>
-
-          <label class="label">{{ item.label }}</label>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { ref, onMounted } from "vue";
-import { sleep } from "@/utils";
-import {
-  CircleCheckFilled,
-  Search,
-  Loading,
-  MoreFilled
-} from "@element-plus/icons-vue";
-const props = defineProps({
-  steps: {
-    type: Array,
-    default: undefined
-  },
-  defaultStartSleep: {
-    type: Number,
-    default: 300
-  },
-  defaultEndSleep: {
-    type: Number,
-    default: 300
-  }
-});
-const emit = defineEmits("confirm");
-const curStep = ref(0);
-const stepList = props.steps || [
-  {
-    label: "模型初始化",
-    value: 0
-  },
-  {
-    label: "相关数据查询",
-    value: 1
-  },
-  {
-    label: "数据分析",
-    value: 2
-  },
-  {
-    label: "分析完成",
-    value: 3
-  }
-];
-const autoAddStep = async () => {
-  curStep.value = 0;
-  await sleep(props.defaultStartSleep);
-  while (curStep.value < stepList.length) {
-    await sleep(5e2);
-    curStep.value++;
-  }
-  await sleep(props.defaultEndSleep);
-  emit("confirm");
-};
-onMounted(() => {
-  autoAddStep();
-})
-</script>
-
-<style lang="scss" scoped>
-
-$black: #000;
-$white: #fff;
-
-.box {
-  position: relative;
-  display: flex;
-  align-items: center;
-  flex-direction: row;
-  width: 100%;
-  height: 100%;
-  box-shadow: 40px 0 65px rgba(#dbeafe, 0.4);
-  padding: 0 80px;
-  box-sizing: border-box;
-  opacity: 1;
-  transform-origin: center;
-}
-.progress {
-  position: relative;
-  display: flex;
-  flex-direction: row;
-  justify-content: space-between;
-  width: 100%;
-}
-
-.bar {
-  position: absolute;
-  top: 50%;
-  left: 50%;
-  background: #dbeafe;
-  width: 98%;
-  margin: auto 1%;
-  height: 3px;
-  border-radius: 10px;
-  transform: translate(-50%, -50%);
-  overflow: hidden;
-
-  &__fill {
-    display: block;
-    background: #1d4ed8;
-    height: 100%;
-  }
-}
-
-.point {
-  position: relative;
-  color: #818cf8;
-  cursor: pointer;
-
-  &:before {
-    content: "";
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    width: 120px;
-    height: 120px;
-    border-radius: 100%;
-    transform: translate(-50%, -50%);
-    transition: 0.3s ease;
-
-    .show-radius & {
-      background: rgba(#000, 0.1);
-    }
-  }
-
-  &--complete,
-  &--active {
-    color: #1d4ed8;
-  }
-}
-
-.label {
-  position: absolute;
-  top: 100%;
-  left: 50%;
-  margin: 16px 0 0 0;
-  font-size: 0.75rem;
-  font-weight: 600;
-  text-transform: uppercase;
-  transform: translate(-50%, 0);
-  white-space: nowrap;
-  font-size: 15px;
-}</style>

+ 0 - 330
src/views/healthManagement/components/BacklogConfigList.vue

@@ -1,330 +0,0 @@
-<template>
-  <div>
-    <el-card class="box-card" shadow="never">
-      <el-row>
-        <el-col :span="16">
-          <el-row>
-            <el-space wrap>
-              <el-select v-model="query.type" placeholder="">
-                <el-option label="全部事项类别" :value="-1" />
-                <el-option
-                  v-for="item in typeList"
-                  :key="item.value"
-                  :label="item.key + '事项'"
-                  :value="item.value"
-                />
-              </el-select>
-              <el-date-picker
-                value-format="YYYY-MM-DD"
-                v-model="queryTime"
-                type="daterange"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-              />
-              <el-select v-model="query.status" placeholder="">
-                <el-option label="全部完成情况" :value="-1" />
-                <el-option
-                  v-for="item in statusList"
-                  :key="item.value"
-                  :label="item.key"
-                  :value="item.value"
-                />
-              </el-select>
-            </el-space>
-          </el-row>
-        </el-col>
-        <el-col :span="8" class="flex">
-          <el-input
-            v-model="query.theme"
-            placeholder="输入事项主题"
-            clearable
-          />
-          <el-button
-            class="ml-2"
-            type="primary"
-            :icon="Search"
-            @click="onSearch"
-            :loading="loading"
-            >查询</el-button
-          >
-        </el-col>
-      </el-row>
-    </el-card>
-    <div class="mt-4">
-      <el-table :data="tableData" style="width: 100%">
-        <el-table-column prop="type" label="事项类别">
-          <template #default="{ row }">
-            {{ formatTypeStr(row.type) }}事项
-          </template>
-        </el-table-column>
-        <el-table-column prop="theme" label="事项主题" />
-        <el-table-column prop="content" label="事项内容">
-          <template #default="{ row }">
-            <div v-if="row.type == 2">
-              <el-space wrap>
-                <div v-if="row.content?.questions?.length">随访问卷</div>
-                <div v-if="row.content?.healthGuidance?.length">
-                  随访健康指导
-                </div>
-              </el-space>
-            </div>
-            <div v-else-if="row.type == 0">
-              {{ row.content }}
-            </div>
-            <div v-else>
-              <el-space wrap>
-                <div v-for="item in row.content" :key="item.id">
-                  <el-tag plain> {{ item.properties.name }}</el-tag>
-                </div>
-              </el-space>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="事项时间">
-          <template #default="{ row }">
-            <el-space wrap>
-              <div v-if="row.frequencyType == 3">
-                {{ row.dates }}
-              </div>
-              <div v-else>
-                {{ row.startDate }} 至 {{ row.endDate }}
-                {{ frequencyType[row.frequencyType] }}
-              </div>
-            </el-space>
-          </template>
-        </el-table-column>
-        <el-table-column prop="status" label="完成情况">
-          <template #default="{ row }">
-            <div :class="statusList[row.status]?.color">
-              {{ statusList[row.status]?.key }}
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column prop="" label="操作" width="180">
-          <template #default="scope">
-            <Auth value="headlthManage:todoList:view">
-              <el-space spacer="|">
-                <el-button
-                  type="primary"
-                  :disabled="scope.row.status == 1"
-                  link
-                  @click="handleEdit(scope.row)"
-                  >编辑</el-button
-                >
-                <el-popconfirm
-                  title="确定要删除此标签吗"
-                  @confirm="onDelete(scope.row.id)"
-                  width="200"
-                >
-                  <template #reference>
-                    <el-link type="danger" :disabled="scope.row.status == 1"
-                      >删除</el-link
-                    >
-                  </template>
-                </el-popconfirm>
-              </el-space>
-            </Auth>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <el-pagination
-        class="mt-4 justify-end"
-        background
-        :current-page="query.page"
-        :page-size="query.pageSize"
-        :total="total"
-        layout="total, prev, pager, next"
-        @current-change="onChangePage"
-      />
-    </div>
-    <el-dialog title="" v-model="visibleEdit" append-to-body>
-      <div>
-        <component :is="cmps[rowData?.type]" isEdit ref="cmpsRef" />
-      </div>
-      <template #footer>
-        <el-button type="primary" @click="handleSaveSubmit">保存修改</el-button>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import {
-  ref,
-  onMounted,
-  onBeforeUnmount,
-  computed,
-  defineAsyncComponent,
-  defineExpose,
-  defineEmits
-} from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { request } from "@/utils/http";
-import { ElMessage } from "element-plus";
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-
-const emits = defineEmits(["success"]);
-const cmps = {
-  0: defineAsyncComponent(() => import("./TodoItemOther.vue")), // 其他
-  1: defineAsyncComponent(() => import("./TodoItemCheck.vue")), // 复查
-  2: defineAsyncComponent(() => import("./TodoItemFollowUp.vue")), // 随访
-  3: defineAsyncComponent(() => import("./TodoItemMonitor.vue")), // 监测
-  4: defineAsyncComponent(() => import("./TodoItemInspect.vue")), // 检查
-  5: defineAsyncComponent(() => import("./TodoItemReturnVisit.vue")) // 回访
-};
-const tableData = ref([]);
-const query = ref({
-  page: 1,
-  pageSize: 15,
-  theme: "",
-  type: -1,
-  status: -1
-});
-const cmpsRef = ref();
-const queryTime = ref("");
-const loading = ref(false);
-const total = ref(0);
-const frequencyType = ["每天", "每周", "每月", "指定日期"];
-const typeList = [
-  {
-    key: "复查",
-    value: 1
-  },
-  {
-    key: "随访",
-    value: 2
-  },
-  {
-    key: "日常监测",
-    value: 3
-  },
-
-  {
-    key: "其他",
-    value: 0
-  }
-
-  // {
-  //   key: "检查",
-  //   value: 4
-  // },
-
-  // {
-  //   key: "回访",
-  //   value: 5
-  // }
-];
-const statusList = [
-  {
-    key: "待完成",
-    value: 0,
-    color: "text-gray-500"
-  },
-  {
-    key: "已完成",
-    value: 1,
-    color: "text-green-500"
-  },
-  {
-    key: "部分完成",
-    value: 2,
-    color: "text-blue-500"
-  }
-];
-const formatTypeStr = type => {
-  return typeList.find(v => v.value === type)?.key;
-};
-const visibleEdit = ref(false);
-
-const rowData = ref({
-  type: 0
-});
-
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const getList = () => {
-  loading.value = true;
-  request
-    .get("dataService/schedule/archive/paginate", {
-      params: {
-        ...query.value,
-        startDate: queryTime.value && queryTime.value[0],
-        endDate: queryTime.value && queryTime.value[1],
-        archiveId: currentArchiveId.value
-      }
-    })
-    .then(resp => {
-      tableData.value = resp.data.list;
-      total.value = resp.data.total;
-    })
-    .finally(() => {
-      loading.value = false;
-    });
-};
-const onSearch = () => {
-  query.value.page = 1;
-  getList();
-};
-const onChangePage = page => {
-  query.value.page = page;
-  getList();
-};
-const handleEdit = row => {
-  visibleEdit.value = true;
-  rowData.value = row;
-  setTimeout(() => {
-    cmpsRef.value?.onInitEditData(row);
-  }, 500);
-  // nextTick(() => {}).then(() => {
-  //   cmpsRef.value?.onInitEditData(row);
-  // });
-};
-const handleSaveSubmit = () => {
-  cmpsRef.value?.onSubmit(pramas => {
-    request
-      .post("/dataService/schedule/update", {
-        // ...rowData.value,
-        id: rowData.value.id,
-        ...pramas
-      })
-      .then(resp => {
-        ElMessage.success(resp.message);
-        visibleEdit.value = false;
-        getList();
-        emits("success");
-      });
-  });
-};
-const onDelete = id => {
-  request.post("dataService/schedule/delete", { id }).then(resp => {
-    ElMessage.success(resp.message);
-    emits("success");
-    getList();
-  });
-};
-
-/** 使用公共函数,避免`removeEventListener`失效 */
-function onkeypress({ code }) {
-  if (code === "Enter") {
-    onSearch();
-  }
-}
-
-onMounted(() => {
-  window.document.addEventListener("keypress", onkeypress);
-});
-
-onBeforeUnmount(() => {
-  window.document.removeEventListener("keypress", onkeypress);
-});
-
-const initData = () => {
-  getList();
-};
-initData();
-
-defineExpose({
-  initData
-});
-</script>

+ 0 - 392
src/views/healthManagement/components/CurrentMonthTodoItems.vue

@@ -1,392 +0,0 @@
-<template>
-  <div class="current-month-todo-items">
-    <div v-for="(item, index) in props.list" :key="index" :id="item.date">
-      <el-card class="mb-2">
-        <template #header>
-          <div
-            :class="isToday(item.date) ? 'bg-orange-200 text-red-500' : ''"
-            class="p-3 flex items-center"
-          >
-            <div class="h-6 w-6" v-if="isToday(item.date)">
-              <CaretRight />
-            </div>
-            {{ item.date }}
-          </div>
-        </template>
-        <div>
-          <div v-if="item.schedules?.length">
-            <div
-              v-for="todoItem in item.schedules"
-              :key="todoItem.id"
-              class="bg-slate-100 mb-2 relative px-2 py-3 flex items-center justify-between w-full"
-            >
-              <div class="flex w-full">
-                <el-button
-                  type="primary"
-                  class="absolute top-3 right-1"
-                  link
-                  :icon="Edit"
-                  @click="handleEditRemark(todoItem, item.date)"
-                  >完成情况备注</el-button
-                >
-                <div @click="handleDone(todoItem, item.date)" class="flex pt-1">
-                  <el-icon
-                    v-if="todoItem.done"
-                    style="color: #67c23a; font-size: 20px"
-                    class="mr-2"
-                    ><SuccessFilled
-                  /></el-icon>
-                  <el-icon v-else style="font-size: 20px" class="mr-2"
-                    ><CircleCheck
-                  /></el-icon>
-                </div>
-                <div class="w-9/12">
-                  <el-text :tag="todoItem.done ? 'del' : 'span'">
-                    <el-text tag="b" :type="todoItem.done ? 'info' : ''" s>{{
-                      todoItem.theme
-                    }}</el-text>
-                  </el-text>
-                  <template v-if="[1, 3].includes(todoItem.type)">
-                    <div class="my-2">
-                      <el-text size="small" type="info"
-                        >{{ typeMap[todoItem.type] }}内容:</el-text
-                      >
-                      <el-space wrap>
-                        <div
-                          v-for="(tag, index) in todoItem.content ||
-                          todoItem.template"
-                          :key="tag + index"
-                        >
-                          <el-tag plain> {{ tag.properties.name }}</el-tag>
-                        </div>
-                      </el-space>
-                    </div>
-                    <div v-if="todoItem.remark">
-                      <el-text size="small" type="info">事项提醒:</el-text>
-                      <el-button
-                        type="primary"
-                        size="small"
-                        :icon="View"
-                        link
-                        @click="
-                          () => {
-                            state.visibleDetail = true;
-                            state.rowData = todoItem;
-                          }
-                        "
-                        >查看</el-button
-                      >
-                    </div>
-                  </template>
-
-                  <template v-else-if="todoItem.type == 2">
-                    <div class="my-2">
-                      <template
-                        v-if="
-                          todoItem.content?.questions?.length ||
-                          todoItem.template?.questions?.length
-                        "
-                      >
-                        <el-text size="small" type="info">随访问卷:</el-text>
-                        <el-button
-                          @click="handleEditQuestion(todoItem)"
-                          type="primary"
-                          size="small"
-                          :icon="Edit"
-                          link
-                        >
-                          {{ todoItem.content ? "查看/修改" : "去填写" }}
-                        </el-button>
-                      </template>
-                    </div>
-                    <div class="mb-2">
-                      <template v-if="todoItem.content?.healthGuidance">
-                        <el-text size="small" type="info"
-                          >随访健康指导:</el-text
-                        >
-                        <el-button
-                          type="primary"
-                          size="small"
-                          :icon="View"
-                          link
-                          @click="
-                            () => {
-                              editContentVisible.healthGuidance = true;
-                              state.rowData = todoItem;
-                            }
-                          "
-                        >
-                          查看
-                        </el-button>
-                      </template>
-                    </div>
-                    <div v-if="todoItem.remark" class="mb-2">
-                      <el-text size="small" type="info">事项提醒:</el-text>
-                      <el-button
-                        type="primary"
-                        size="small"
-                        :icon="View"
-                        link
-                        @click="
-                          () => {
-                            state.visibleDetail = true;
-                            state.rowData = todoItem;
-                          }
-                        "
-                        >查看</el-button
-                      >
-                    </div>
-                    <div class="mb-2">
-                      <template v-if="todoItem.content?.visitGuidance">
-                        <el-text size="small" type="info"
-                          >随访人员指导:</el-text
-                        >
-                        <el-button
-                          type="primary"
-                          size="small"
-                          :icon="View"
-                          link
-                          @click="
-                            () => {
-                              editContentVisible.visitGuidance = true;
-                              state.rowData = todoItem;
-                            }
-                          "
-                        >
-                          查看
-                        </el-button>
-                      </template>
-                    </div>
-                  </template>
-
-                  <template v-else-if="todoItem.type == 0">
-                    <div class="my-2">
-                      <el-text size="small" type="info"
-                        >事项内容:{{ todoItem.content }}</el-text
-                      >
-                    </div>
-                    <div v-if="todoItem.remark">
-                      <el-text size="small" type="info">事项提醒:</el-text>
-                      <el-button
-                        type="primary"
-                        size="small"
-                        :icon="View"
-                        link
-                        @click="
-                          () => {
-                            state.visibleDetail = true;
-                            state.rowData = todoItem;
-                          }
-                        "
-                        >查看</el-button
-                      >
-                    </div>
-                  </template>
-                  <div v-if="todoItem?.comment">
-                    <el-text size="small" type="info"
-                      >完成情况备注: {{ todoItem?.comment }}</el-text
-                    >
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div v-else>
-            <el-empty />
-          </div>
-        </div>
-      </el-card>
-    </div>
-    <el-dialog
-      title="完成情况备注"
-      append-to-body
-      v-model="state.visibleRemark"
-    >
-      <div class="mt-2">
-        <el-input
-          v-model="state.rowData.comment"
-          placeholder="选填,输入事项完成备注信息"
-          :autosize="{ minRows: 6, maxRows: 10 }"
-          type="textarea"
-        />
-      </div>
-      <template #footer>
-        <el-button type="primary" plain @click="state.visibleRemark = false"
-          >取消</el-button
-        >
-        <el-button type="primary" @click="onSaveRemark()">确定</el-button>
-      </template>
-    </el-dialog>
-    <el-dialog title="事项提醒" append-to-body v-model="state.visibleDetail">
-      <div>
-        <div v-html="state.rowData.remark" />
-      </div>
-    </el-dialog>
-
-    <el-dialog
-      title="随访问卷"
-      append-to-body
-      v-model="editContentVisible.questions"
-    >
-      <!-- <div>
-        <div v-if="state.rowData.content?.questions?.length">
-          <div
-            v-for="(item, index) in state.rowData.content?.questions"
-            :key="index"
-            class="m-1 bg-gray-100 rounded p-4 mb-3"
-          >
-            <SimpleQuestionItem :info="item" :id="item.id" :edit="true" />
-          </div>
-          <el-button type="primary" @click="onSaveQuestio">保存</el-button>
-        </div>
-      </div> -->
-
-      <customSurvey
-        :content="{
-          content:
-            state.rowData.content?.questions ||
-            state.rowData.template?.questions,
-          logicCode:
-            state.rowData.content?.logicCode ||
-            state.rowData.template?.logicCode
-        }"
-        @onSave="onSaveQuestion"
-        ref="customSurveyRef"
-      />
-      <!-- <customSurvey
-        :content="{
-          content: state.rowData.template?.questions,
-          logicCode: state.rowData.template?.logicCode
-        }"
-        @onSave="onSaveQuestion"
-      /> -->
-    </el-dialog>
-    <el-dialog
-      title="随访健康指导"
-      append-to-body
-      v-model="editContentVisible.healthGuidance"
-    >
-      <div>
-        <div v-html="state.rowData.content.healthGuidance" />
-      </div>
-    </el-dialog>
-    <el-dialog
-      title="随访人员指导"
-      append-to-body
-      v-model="editContentVisible.visitGuidance"
-    >
-      <div>
-        <div v-html="state.rowData.content.visitGuidance" />
-      </div>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import { defineProps, reactive, defineEmits, defineOptions, ref } from "vue";
-
-import {
-  CaretRight,
-  SuccessFilled,
-  CircleCheck,
-  View,
-  Edit
-} from "@element-plus/icons-vue";
-import { request } from "@/utils";
-import { ElMessage } from "element-plus";
-import customSurvey from "./customSurvey.vue";
-const typeMap = ["其他", "复查", "随访", "监测", "检查", "回访"];
-const props = defineProps({
-  list: {
-    type: Array
-  },
-  currentDate: {
-    type: String
-  },
-  uncompleted: Boolean // 是否未完成
-});
-const emits = defineEmits(["success"]);
-const state = reactive({
-  visibleRemark: false,
-  visibleDetail: false,
-  visibleFollowUp: false,
-  rowData: {},
-  date: ""
-});
-const customSurveyRef = ref();
-const editContentVisible = reactive({
-  questions: false,
-  healthGuidance: false,
-  visitGuidance: false
-});
-const isToday = date => {
-  return props.currentDate == date && props.uncompleted;
-};
-const handleEditRemark = (item, date) => {
-  state.rowData = item;
-  state.date = date;
-  state.visibleRemark = true;
-};
-const onSaveRemark = () => {
-  const item = state.rowData;
-  request
-    .post("dataService/schedule/todo/comment", {
-      id: item.id,
-      date: state.date,
-      comment: item.comment
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      state.visibleRemark = false;
-      emits("success");
-    });
-};
-const handleEditQuestion = todoItem => {
-  editContentVisible.questions = true;
-  state.rowData = todoItem;
-  setTimeout(() => {
-    customSurveyRef.value?.init();
-  }, 500);
-};
-const handleDone = (item, date) => {
-  request
-    .post("dataService/schedule/checkTodo", {
-      id: item.id,
-      date: date,
-      status: item.done ? 0 : 1
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      emits("success");
-    });
-};
-const onSaveQuestion = ({ questions, viewQuestions }) => {
-  request
-    .post("dataService/schedule/todo/content", {
-      id: state.rowData.id,
-      date: state.rowData.startDate,
-      content: {
-        ...state.rowData.content,
-        questions: questions,
-        viewQuestions: viewQuestions
-      }
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      editContentVisible.questions = false;
-      emits("success");
-    });
-};
-
-defineOptions({
-  name: "CurrentMonthTodoItems"
-});
-</script>
-<style lang="scss" scoped>
-.current-month-todo-items {
-  ::v-deep {
-    .el-card__header {
-      padding: 0;
-    }
-  }
-}
-</style>

+ 0 - 423
src/views/healthManagement/components/DataCalc.vue

@@ -1,423 +0,0 @@
-<template>
-  <div class="space-y-4">
-    <slot name="title"></slot>
-    <p class="text-gray-600 font-bold mb-2">公式设置:</p>
-    <div class="space-y-4">
-      <div
-        v-for="(item, index) in conditions"
-        :key="index"
-        class="flex flex-wrap space-x-2"
-      >
-        <el-select-v2
-          v-model="item.nodeId"
-          placeholder="请选择项目"
-          filterable
-          :options="nodes"
-          @change="val => projectChange(item, val)"
-        ></el-select-v2>
-
-        <el-select v-model="item.operator" placeholder="运算符" class="w-24">
-          <el-option
-            v-for="(operator, operatorIndex) in operators"
-            :key="operatorIndex"
-            :label="operator.value"
-            :value="operator.value"
-          ></el-option>
-        </el-select>
-
-        <el-input
-          v-model="item.value"
-          placeholder="请输入达标值"
-          class="w-40"
-          clearable
-        ></el-input>
-
-        <el-select v-model="item.unit" placeholder="单位" class="w-24">
-          <el-option
-            v-for="(unit, unitIndex) in item.units"
-            :key="unitIndex"
-            :label="unit"
-            :value="unit"
-          ></el-option>
-        </el-select>
-
-        <el-select
-          v-if="!index"
-          v-model="item.condition"
-          class="w-40"
-          placeholder="(选填)附加条件"
-          clearable
-          @change="v => v && conditions.length === 1 && addCondition(0)"
-          @clear="conditions.splice(1, 1)"
-        >
-          <el-option
-            v-for="(condition, conditionIdx) in addConditions"
-            :key="conditionIdx"
-            :label="condition.label"
-            :value="condition.value"
-          ></el-option>
-        </el-select>
-        <!-- <el-button type="primary" link @click="addCondition(index)">
-          <Plus class="w-4" />
-          <span>添加条件</span>
-        </el-button>
-        <el-button
-          v-if="conditions.length > 1"
-          type="danger"
-          link
-          @click="removeCondition(index)"
-        >
-          <Delete class="w-4" />
-          <span>删除</span>
-        </el-button> -->
-      </div>
-    </div>
-    <p class="text-gray-600 font-bold mb-2">设置数据时间范围:</p>
-    <el-date-picker
-      v-model="date"
-      type="daterange"
-      start-placeholder="请选择日期"
-      end-placeholder="请选择日期"
-      format="YYYY-MM-DD"
-      value-format="YYYY-MM-DD"
-      clearable
-    />
-    <div class="flex items-center justify-center">
-      <el-button class="w-full" type="primary" size="large" @click="startCalc"
-        >开始计算</el-button
-      >
-    </div>
-    <template v-if="calcResult.visible">
-      <p class="text-gray-600 font-bold mb-2">计算结果:</p>
-      <div class="text-sm text-gray-800 space-y-2">
-        <div>
-          <span>时间范围:</span>
-          <span>{{ calcResult.date.join("至") }}</span>
-        </div>
-        <div>
-          <span>达标条件:</span>
-          <span>{{ calcResult.condition }}</span>
-        </div>
-        <div>
-          <span>找到数据:</span>
-          <span>{{ calcResult.total }}条</span>
-        </div>
-        <div>
-          <span>达标率为:</span>
-          <span class="text-blue-600">{{ calcResult.rate }}%</span>
-        </div>
-      </div>
-      <div class="overflow-x-auto w-full">
-        <div v-for="(item, index) in list" :key="index">
-          <table class="bg-white text-gray-700 table-fixed">
-            <tr class="font-bold">
-              <td class="border border-solid border-gray-100 p-2">项目</td>
-              <td
-                class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-                v-for="(col, index) in item.list[0].list"
-                :key="index"
-              >
-                {{ dayjs(col.date * 1000).format("YYYY-MM-DD HH:mm:ss") }}
-              </td>
-            </tr>
-            <tr v-for="(child, childIdx) in item.list" :key="childIdx">
-              <td
-                class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-              >
-                {{ child.name }}
-              </td>
-              <td
-                v-for="(col, colIdx) in child.list"
-                :key="colIdx"
-                class="border border-solid border-gray-100"
-              >
-                <div class="p-2 text-sm">
-                  <span class="align-middle"
-                    >{{ col.value
-                    }}{{ col.unit && col.unit != "-" ? col.unit : "" }}
-                  </span>
-                  <template v-if="col.reference">
-                    <el-tooltip>
-                      <QuestionFilled
-                        class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                      />
-                      <template #content>
-                        <div class="text-sm">参考范围:{{ col.reference }}</div>
-                      </template>
-                    </el-tooltip>
-                  </template>
-                </div>
-              </td>
-            </tr>
-          </table>
-        </div>
-      </div>
-    </template>
-  </div>
-</template>
-
-<script setup>
-import { ref, shallowRef } from "vue";
-import { ElMessage } from "element-plus";
-import {
-  Plus,
-  ArrowUp,
-  ArrowDown,
-  Delete,
-  QuestionFilled
-} from "@element-plus/icons-vue";
-import { request } from "@/utils";
-import { useRoute, useRouter } from "vue-router";
-import dayjs from "dayjs";
-const [route, router] = [useRoute(), useRouter()];
-
-const conditions = ref([
-  {
-    operator: "",
-    condition: "",
-    value: "",
-    unit: "",
-    nodeId: "",
-    units: []
-  }
-]);
-const date = ref([
-  dayjs(Date.now()).subtract(365, "day").format("YYYY-MM-DD"),
-  dayjs(Date.now()).add(1, "day").format("YYYY-MM-DD")
-]);
-const operators = [
-  { label: "大于", value: ">" },
-  { label: "大于等于", value: "≥" },
-  { label: "小于", value: "<" },
-  { label: "小于等于", value: "≤" },
-  { label: "等于", value: "=" }
-];
-const addConditions = [
-  {
-    label: "并且",
-    value: "and"
-  }
-];
-
-const addCondition = index => {
-  conditions.value.splice(index + 1, 0, {
-    operator: "",
-    condition: "",
-    value: "",
-    unit: "",
-    nodeId: "",
-    units: []
-  });
-};
-const removeCondition = index => {
-  conditions.value.splice(index, 1);
-};
-
-const nodes = shallowRef([]);
-const searchNodes = async () => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 9999,
-      tag: "身体物质"
-    }
-  });
-  nodes.value = (data.list || []).map(v => ({
-    value: v.id,
-    label: v.properties?.name
-  }));
-};
-searchNodes();
-
-const searchRelateNodes = async (id, relationship) => {
-  if (!id) return;
-  const { data } = await request.get(`/graphService/open/node/related`, {
-    params: {
-      id,
-      relationship
-    }
-  });
-  return data;
-};
-const projectChange = async (item, id) => {
-  const scope = await searchRelateNodes(id, "默认单位与范围");
-  if (scope?.length) {
-    item.units = scope.map(v => v.properties?.name).filter(v => v);
-    item.unit = item.units[0] || "";
-  } else {
-    item.units = [];
-    item.unit = "";
-  }
-};
-
-const list = ref([]);
-const calcResult = ref({
-  date: [],
-  condition: "",
-  total: 0,
-  rate: 0,
-  visible: false
-});
-const countSatisfyingData = (data, conditions) => {
-  let count = 0;
-  console.log("数据", data);
-  console.log("条件", conditions);
-  // 遍历数据
-  data.forEach(item => {
-    let satisfyGroupConditions = {}; // 记录每个组内的条件是否满足
-
-    // 遍历条件
-    let satisfyAllConditions = true; // 标记是否满足所有条件
-    conditions.forEach((condition, conditionIdx) => {
-      // 获取条件的操作符
-      const operator = operators.find(
-        op => op.value === condition.operator
-      ).value;
-
-      // 获取当前项目的值
-      const subItem = item.find(subItem => subItem.id === condition.nodeId);
-      console.log(`操作符:${operator};当前值`, subItem?.value, condition);
-      if (subItem && subItem.value !== undefined) {
-        // 检查条件
-        switch (operator) {
-          case ">":
-            if (!(parseFloat(subItem.value) > parseFloat(condition.value))) {
-              satisfyAllConditions = false;
-            }
-            break;
-          case "≥":
-            if (!(parseFloat(subItem.value) >= parseFloat(condition.value))) {
-              satisfyAllConditions = false;
-            }
-            break;
-          case "<":
-            if (!(parseFloat(subItem.value) < parseFloat(condition.value))) {
-              satisfyAllConditions = false;
-            }
-            break;
-          case "≤":
-            if (!(parseFloat(subItem.value) <= parseFloat(condition.value))) {
-              satisfyAllConditions = false;
-            }
-            break;
-          case "=":
-            if (!(parseFloat(subItem.value) === parseFloat(condition.value))) {
-              satisfyAllConditions = false;
-            }
-            break;
-          default:
-            break;
-        }
-      } else {
-        satisfyAllConditions = false; // 如果项目或值不存在,条件不满足
-      }
-      console.log("本次结果:", satisfyAllConditions);
-    });
-    // 如果满足所有条件,计数加一
-    if (satisfyAllConditions) {
-      count++;
-    }
-  });
-
-  return count;
-};
-const formatCalcResult = () => {
-  try {
-    calcResult.value.date = date.value;
-    let s = "";
-    conditions.value.forEach(v => {
-      const node = nodes.value.find(v2 => v.nodeId == v2.value);
-      s += `${node.label}${v.operator}${v.value}${v.unit}${
-        v.condition ? "并且" : ";"
-      }`;
-    });
-    calcResult.value.condition = s;
-    let count = 0;
-    const tmpList = [];
-    list.value.forEach(v1 => {
-      v1.list.forEach(v2 => {
-        count = v2.list.length;
-        v2.list.forEach((v3, k3) => {
-          if (!tmpList[k3]) {
-            tmpList[k3] = [v3];
-          } else {
-            tmpList[k3].push(v3);
-          }
-        });
-      });
-    });
-    calcResult.value.total = count;
-    console.log(calcResult.value);
-    const c = countSatisfyingData(tmpList, conditions.value);
-    calcResult.value.rate = count ? (c / count).toFixed(2) * 100 : 0;
-    calcResult.value.visible = true;
-  } catch (error) {
-    ElMessage.error("计算结果异常:" + error.message);
-  }
-};
-const startCalc = async () => {
-  const req = {
-    archivesId: route.query.archivesId,
-    nodeIds: conditions.value.map(v => v.nodeId),
-    dates: date.value,
-    querys: conditions.value.map(v => ({
-      nodeId: v.nodeId,
-      unit: v.unit
-    }))
-  };
-  console.log(req);
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/query",
-    req
-  );
-  const temp = [];
-  data.list.forEach(v => {
-    if (v.list.length > 1) {
-      v.list.forEach((v2, k2) => {
-        v2.list = v2.list.filter(v3 => v3.value || v3.value === 0);
-      });
-      // v.list.sort((a, b) => b.list.length - a.list.length);
-      v.list.forEach((v2, k2) => {
-        // 过滤重复 取最大值
-        const dateVal = {};
-        v2.list = v2.list
-          .filter(v3 => {
-            if (!dateVal[v3.date]) {
-              dateVal[v3.date] = v3.value;
-              return true;
-            } else {
-              dateVal[v3.date] = Math.max(dateVal[v3.date], v3.value);
-              return false;
-            }
-          })
-          .map(v3 => {
-            v3.value = dateVal[v3.date] || v3.value;
-            return v3;
-          });
-      });
-      v.list.forEach((v2, k2) => {
-        const dates = {};
-        const filterDates = v.list
-          .map(v2 => v2.list.map(v3 => v3.date))
-          .flat()
-          .map(v2 => {
-            if (!dates[v2]) {
-              dates[v2] = 1;
-            } else {
-              dates[v2]++;
-            }
-            return v2;
-          })
-          .filter(v2 => dates[v2] > 1);
-
-        v2.list = v2.list.filter(v3 => filterDates.includes(v3.date));
-      });
-    }
-  });
-  console.log(data.list);
-  list.value = data.list;
-  formatCalcResult();
-};
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 45
src/views/healthManagement/components/DataCalcTool.vue

@@ -1,45 +0,0 @@
-<template>
-  <div>
-    <div
-      v-for="(item, index) in list"
-      :key="index"
-      class="border border-solid border-gray-100 shadow rounded mb-2 p-4"
-    >
-      <component :is="DataCalc">
-        <template #title>
-          <div class="flex items-center justify-between">
-            <!-- <div v-if="list.length <= 1"></div> -->
-            <el-button type="primary" link @click="list.splice(index, 0, {})">
-              <Plus class="w-4" />
-              <span>新增计算</span>
-            </el-button>
-            <el-button
-              v-if="list.length > 1"
-              type="danger"
-              link
-              @click="list.splice(index, 1)"
-              ><Delete class="w-4" /><span>删除该计算</span></el-button
-            >
-          </div>
-        </template>
-      </component>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { ref, shallowRef, defineAsyncComponent } from "vue";
-import { ElMessage } from "element-plus";
-import {
-  Plus,
-  ArrowUp,
-  ArrowDown,
-  Delete,
-  QuestionFilled
-} from "@element-plus/icons-vue";
-const DataCalc = defineAsyncComponent(() => import("./DataCalc.vue"));
-
-const list = ref([{}]);
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 288
src/views/healthManagement/components/DialogBacklog copy 2.vue

@@ -1,288 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-      title="待办事项"
-      v-model="dialogVisible"
-      fullscreen
-      :show-close="false"
-    >
-      <template #header>
-        <el-card border>
-          <template #header>
-            <div class="flex items-center justify-between">
-              <h3>待办事项</h3>
-              <div class="text-right">
-                <el-button type="danger" plain @click="dialogVisible = false"
-                  >关闭</el-button
-                >
-              </div>
-            </div>
-          </template>
-          <div>
-            <div>
-              <el-row :gutter="40">
-                <el-col :span="6">
-                  <div>
-                    <ComponentProfileCard :id="currentArchiveId" />
-                    <div class="pt-5" />
-                    <div
-                      v-for="(menu, menuIdx) in menus"
-                      :key="menuIdx"
-                      class="flex items-center justify-between py-3 px-4 border-0 border-b border-solid border-gray-100 cursor-pointer text-sm hover:bg-gray-50"
-                      :class="{
-                        'bg-gray-50 text-blue-500': curMenu === menu.key
-                      }"
-                      @click="curMenu = menu.key"
-                    >
-                      <span>{{ menu.label }}</span>
-                      <ArrowRight class="w-4" />
-                    </div>
-                    <div class="pt-3">
-                      <el-text tag="b">选择指定月份或日期处理待办</el-text>
-                      <div
-                        class="border border-solid border-gray-100 pt-3 mt-3"
-                      >
-                        <div class="flex justify-between">
-                          <el-date-picker
-                            v-model="state.date"
-                            type="month"
-                            placeholder="选择月份"
-                            value-format="YYYY-MM"
-                            @change="handleMonth"
-                            class="ml-2"
-                          />
-                          <div class="pr-2">
-                            <el-button
-                              type="primary"
-                              link
-                              @click="handleBackToday"
-                              >返回今天</el-button
-                            >
-                          </div>
-                        </div>
-                        <el-calendar
-                          v-model="state.calendarValue"
-                          ref="calendarRef"
-                        >
-                          <template #header>
-                            <div />
-                          </template>
-                        </el-calendar>
-                      </div>
-                      <div class="pt-3">
-                        <el-text tag="b" class="text-base">说明</el-text>
-                        <div class="flex items-center pt-2">
-                          <div
-                            class="bg-red-600 w-2.5 h-2.5 rounded-full inline-block mr-2"
-                          />
-                          <span class="text-sm"
-                            >表示当天用户有待办事项需完成</span
-                          >
-                        </div>
-                        <div class="flex items-center mb-3 mt-3">
-                          <div
-                            class="bg-green-600 w-2.5 h-2.5 rounded-full inline-block mr-2"
-                          />
-                          <span class="text-sm"
-                            >表示当天用户所有待办事项已完成</span
-                          >
-                        </div>
-                        <div class="flex items-center">
-                          <div
-                            class="bg-blue-600 w-2.5 h-2.5 rounded-full inline-block mr-2"
-                          />
-                          <span class="text-sm"
-                            >表示当天用户还有部分待办事项需完成</span
-                          >
-                        </div>
-                      </div>
-                    </div>
-                  </div>
-                </el-col>
-                <el-col :span="18" class="border-0 border-l-8 border-gray-100">
-                  <el-form label-width="120px" label-position="left">
-                    <el-form-item label="选择事项类别:" required>
-                      <el-radio-group v-model="state.itemType">
-                        <el-radio
-                          v-for="(item, index) in itemTypeList"
-                          :key="index"
-                          :label="item.value"
-                        >
-                          {{ item.key }}</el-radio
-                        >
-                      </el-radio-group>
-                    </el-form-item>
-                  </el-form>
-                  <component :is="cmps[state.itemType]" />
-                </el-col>
-              </el-row>
-            </div>
-          </div>
-        </el-card>
-      </template>
-    </el-dialog>
-    <ComponentDialogBacklogCheckbox
-      v-model:show="state.visibleBacklogHandle"
-      :date="state.time"
-      :type="props.type"
-      @success="getList"
-    />
-  </div>
-</template>
-<script lang="ts" setup>
-import { request } from "@/utils";
-import moment from "moment";
-import { ArrowRight } from "@element-plus/icons-vue";
-import {
-  ref,
-  computed,
-  defineProps,
-  defineEmits,
-  watch,
-  reactive,
-  defineAsyncComponent
-} from "vue";
-import ComponentDialogBacklogCheckbox from "./DialogBacklogCheckbox.vue";
-import ComponentProfileCard from "./ProfileCard.vue";
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  type: {
-    type: String,
-    default: "edit"
-  }
-});
-const emits = defineEmits(["update:show"]);
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-const isEdit = computed(() => {
-  return props.type == "edit";
-});
-
-const itemTypeList = ref([
-  {
-    key: "复查",
-    value: 1
-  },
-  {
-    key: "随访",
-    value: 2
-  },
-  {
-    key: "日常监测",
-    value: 3
-  },
-
-  {
-    key: "其他",
-    value: 4
-  },
-
-  {
-    key: "检查",
-    value: 5
-  },
-
-  {
-    key: "回访",
-    value: 6
-  }
-]);
-const cmps = {
-  1: defineAsyncComponent(() => import("./TodoItemCheck.vue")), // 复查
-  2: defineAsyncComponent(() => import("./TodoItemFollowUp.vue")) // 随访
-};
-const calendarRef = ref();
-const menus = [
-  {
-    label: "新增待办事项",
-    key: "NewTodoItems"
-  },
-  {
-    label: "待办事项管理",
-    key: "TodoManagement"
-  },
-  {
-    label: "本月待办处理",
-    key: "HandleMonthTodo"
-  }
-];
-const state = reactive({
-  date: moment().format("YYYY-MM"),
-  calendarValue: "",
-  visibleBacklogHandle: false,
-  time: "",
-  itemList: {},
-  itemDateList: [],
-  itemType: 1 // 事项类别
-});
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      getList();
-    } else {
-    }
-  }
-);
-const getList = () => {
-  request
-    .get("/platformApi/dataService/diseaseManage/todoList", {
-      params: {
-        archiveId: currentArchiveId.value,
-        date: state.date
-      }
-    })
-    .then(resp => {
-      const itemObj = {};
-      resp.data.map(v => {
-        itemObj[v.date] = v;
-      });
-
-      state.itemList = itemObj;
-
-      state.itemDateList = resp.data
-        .filter(v => {
-          return v.checkItems;
-        })
-        .map(v => v.date);
-    });
-};
-const handleMonth = date => {
-  state.calendarValue = date;
-  getList();
-};
-const handleBackToday = () => {
-  calendarRef.value.selectDate("today");
-};
-
-const handleCheckDate = date => {
-  state.time = date.day;
-  state.visibleBacklogHandle = true;
-};
-</script>
-<style scoped lang="scss">
-::v-deep .el-calendar__button-group {
-  display: none;
-}
-::v-deep .el-calendar-table .el-calendar-day {
-  text-align: center;
-}
-.item-card {
-  height: 100%;
-}
-</style>

+ 0 - 187
src/views/healthManagement/components/DialogBacklog copy.vue

@@ -1,187 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-      title="待办事项"
-      v-model="dialogVisible"
-      fullscreen
-      :show-close="false"
-    >
-      <template #header>
-        <el-card border>
-          <template #header>
-            <div class="flex items-center justify-between">
-              <div>
-                <ComponentProfileCard
-                  :id="currentArchiveId"
-                ></ComponentProfileCard>
-              </div>
-              <div class="text-right">
-                <el-button type="danger" plain @click="dialogVisible = false"
-                  >关闭</el-button
-                >
-              </div>
-            </div>
-          </template>
-          <div>
-            <div>
-              <el-date-picker
-                v-model="state.date"
-                type="month"
-                placeholder="选择月份"
-                value-format="YYYY-MM"
-                @change="handleMonth"
-                class="ml-2"
-              />
-
-              <el-text class="ml-2" style="color: #e6a23c" v-if="isEdit"
-                >温馨提示:您可以通过点击日历日期进行待办事项查看和管理</el-text
-              >
-            </div>
-            <el-calendar v-model="state.calendarValue">
-              <template #header>
-                <div></div>
-              </template>
-              <template #date-cell="{ data }">
-                <div @click="handleCheckDate(data)" class="item-card">
-                  <p :class="data.isSelected ? 'is-selected' : ''">
-                    {{ data.day.split("-").slice(1).join("-") }}
-                    {{ data.isSelected ? "✔️" : "" }}
-                  </p>
-                  <div style="height: calc(100% - 20px)">
-                    <el-scrollbar v-if="state.itemDateList.includes(data.day)">
-                      <div
-                        v-for="(item, index) in state.itemList[data.day]
-                          ?.checkItems"
-                        :key="index"
-                      >
-                        <el-text
-                          :tag="item.done ? 'del' : 'span'"
-                          line-clamp="1"
-                          size="small"
-                          >{{ index + 1 }}.{{
-                            item.type == 2
-                              ? `${item.name}回访`
-                              : item.type == 0
-                              ? `${item.name}`
-                              : item.content
-                          }}
-                        </el-text>
-                      </div>
-                    </el-scrollbar>
-                  </div>
-                </div>
-              </template>
-            </el-calendar>
-          </div>
-        </el-card>
-      </template>
-      <div>
-        <!-- <el-card class="mb-4" v-if="!isEdit">
-          <div>
-            <ComponentProfileCard :id="currentArchiveId"></ComponentProfileCard>
-          </div>
-        </el-card> -->
-      </div>
-    </el-dialog>
-    <ComponentDialogBacklogCheckbox
-      v-model:show="state.visibleBacklogHandle"
-      :date="state.time"
-      :type="props.type"
-      @success="getList"
-    ></ComponentDialogBacklogCheckbox>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request } from "@/utils";
-import moment from "moment";
-import { ref, computed, defineProps, defineEmits, watch, reactive } from "vue";
-import ComponentDialogBacklogCheckbox from "./DialogBacklogCheckbox.vue";
-import ComponentProfileCard from "./ProfileCard.vue";
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  type: {
-    type: String,
-    default: "edit"
-  }
-});
-const emits = defineEmits(["update:show"]);
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-const isEdit = computed(() => {
-  return props.type == "edit";
-});
-const state = reactive({
-  date: moment().format("YYYY-MM"),
-  calendarValue: "",
-  visibleBacklogHandle: false,
-  time: "",
-  itemList: {},
-  itemDateList: []
-});
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      getList();
-    } else {
-    }
-  }
-);
-const getList = () => {
-  request
-    .get("/platformApi/dataService/diseaseManage/todoList", {
-      params: {
-        archiveId: currentArchiveId.value,
-        date: state.date
-      }
-    })
-    .then(resp => {
-      let itemObj = {};
-      resp.data.map(v => {
-        itemObj[v.date] = v;
-      });
-
-      state.itemList = itemObj;
-
-      state.itemDateList = resp.data
-        .filter(v => {
-          return v.checkItems;
-        })
-        .map(v => v.date);
-    });
-};
-const handleMonth = date => {
-  state.calendarValue = date;
-  getList();
-};
-const handleCheckDate = date => {
-  state.time = date.day;
-  state.visibleBacklogHandle = true;
-};
-</script>
-<style scoped lang="scss">
-::v-deep .el-calendar__button-group {
-  display: none;
-}
-::v-deep .el-calendar-table .el-calendar-day {
-  height: 170px;
-}
-.item-card {
-  height: 100%;
-}
-</style>

+ 0 - 551
src/views/healthManagement/components/DialogBacklog.vue

@@ -1,551 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-      title="待办事项"
-      v-model="dialogVisible"
-      fullscreen
-      :show-close="false"
-    >
-      <template #header>
-        <el-card border>
-          <template #header>
-            <div class="flex items-center justify-between">
-              <h3>待办事项</h3>
-              <div class="text-right">
-                <el-button type="danger" plain @click="dialogVisible = false"
-                  >关闭</el-button
-                >
-              </div>
-            </div>
-          </template>
-          <div>
-            <div>
-              <el-row :gutter="40">
-                <el-col :span="6">
-                  <div>
-                    <ComponentProfileCard :id="currentArchiveId" />
-                    <div class="pt-5" />
-                    <!-- <Auth value="headlthManage:todoList:edit">
-                      <div
-                        class="flex items-center justify-between py-3 px-4 border-0 border-b border-solid border-gray-100 cursor-pointer text-sm hover:bg-gray-50"
-                        :class="{
-                          'bg-gray-50 text-blue-500': curMenu === 'NewTodoItems'
-                        }"
-                        @click="handleChangeCurMenu('NewTodoItems')"
-                      >
-                        <span>新增待办事项</span>
-                        <ArrowRight class="w-4" />
-                      </div>
-                    </Auth> -->
-                    <div v-for="(menu, menuIdx) in menus" :key="menuIdx">
-                      <div
-                        class="flex items-center justify-between py-3 px-4 border-0 border-b border-solid border-gray-100 cursor-pointer text-sm hover:bg-gray-50"
-                        :class="{
-                          'bg-gray-50 text-blue-500': curMenu === menu.key
-                        }"
-                        v-if="menuIdx == 2 || hasAuth(menu.auth)"
-                        @click="handleChangeCurMenu(menu.key)"
-                      >
-                        <span>{{ menu.label }} </span>
-                        <ArrowRight class="w-4" />
-                      </div>
-                    </div>
-                    <div class="pt-3">
-                      <el-text tag="b">选择指定月份或日期处理待办</el-text>
-                      <div
-                        class="border border-solid border-gray-100 pt-3 mt-3"
-                      >
-                        <div class="flex justify-between">
-                          <el-date-picker
-                            v-model="state.date"
-                            type="month"
-                            placeholder="选择月份"
-                            value-format="YYYY-MM"
-                            format="YYYY年MM月"
-                            @change="handleMonth"
-                            class="ml-2"
-                          />
-                          <div class="pr-2">
-                            <el-button
-                              type="primary"
-                              link
-                              @click="handleBackToday"
-                              >返回今天</el-button
-                            >
-                          </div>
-                        </div>
-
-                        <el-calendar
-                          v-model="state.calendarValue"
-                          ref="calendarRef"
-                        >
-                          <template #date-cell="{ data }">
-                            <div
-                              class="h-full flex flex-col items-center justify-center"
-                              @click="onLiclick(data.day)"
-                            >
-                              <div class="relative">
-                                <div class="text-sm">
-                                  {{ data.day.split("-").slice(2).join("-") }}
-                                </div>
-                                <template
-                                  v-if="state.itemDateList[data.day]?.length"
-                                >
-                                  <div
-                                    class="w-2 h-2 absolute rounded top-2"
-                                    :class="
-                                      itemStatusList[
-                                        formatDot(state.itemDateList[data.day])
-                                      ].color
-                                    "
-                                    style="left: 5px"
-                                  />
-                                  <div class="w-12 text-gray-400 text-xs">
-                                    <div
-                                      v-if="
-                                        state.itemDateList[data.day]?.length
-                                      "
-                                    >
-                                      {{
-                                        state.itemDateList[data.day]?.length
-                                      }}项
-                                    </div>
-                                  </div>
-                                </template>
-                              </div>
-                            </div>
-                          </template>
-                        </el-calendar>
-                      </div>
-                      <div class="pt-3">
-                        <el-text tag="b" class="text-base">说明</el-text>
-                        <div class="flex items-center pt-2">
-                          <div
-                            class="bg-red-600 w-2.5 h-2.5 rounded-full inline-block mr-2"
-                          />
-                          <span class="text-sm"
-                            >表示当天用户有待办事项需完成</span
-                          >
-                        </div>
-                        <div class="flex items-center mb-3 mt-3">
-                          <div
-                            class="bg-green-600 w-2.5 h-2.5 rounded-full inline-block mr-2"
-                          />
-                          <span class="text-sm"
-                            >表示当天用户所有待办事项已完成</span
-                          >
-                        </div>
-                        <div class="flex items-center">
-                          <div
-                            class="bg-blue-600 w-2.5 h-2.5 rounded-full inline-block mr-2"
-                          />
-                          <span class="text-sm"
-                            >表示当天用户还有部分待办事项需完成</span
-                          >
-                        </div>
-                      </div>
-                    </div>
-                  </div>
-                </el-col>
-                <el-col
-                  :span="18"
-                  class="border-0 border-l-8 border-gray-100 relative"
-                >
-                  <template v-if="curMenu == 'NewTodoItems'">
-                    <el-form label-width="120px" label-position="left">
-                      <el-form-item label="选择事项类别:" required>
-                        <el-radio-group v-model="state.itemType">
-                          <el-radio
-                            v-for="(item, index) in itemTypeList"
-                            :key="index"
-                            :label="item.value"
-                          >
-                            {{ item.key }}
-                          </el-radio>
-                        </el-radio-group>
-                      </el-form-item>
-                    </el-form>
-                    <div class="">
-                      <el-scrollbar height="calc(100vh - 260px)">
-                        <component :is="cmps[state.itemType]" ref="cmpsRef" />
-                      </el-scrollbar>
-                    </div>
-                  </template>
-                  <template v-else-if="curMenu === 'TodoManagement'">
-                    <BacklogConfigList
-                      ref="BacklogConfigListRef"
-                      @success="getList"
-                    />
-                  </template>
-                  <template v-else>
-                    <el-scrollbar height="calc(100vh - 160px)">
-                      <template v-if="state.todoDurationList.length">
-                        <KeepAlive include="CurrentMonthTodoItems">
-                          <component
-                            :is="currentMonthTodoItems"
-                            :list="state.todoDurationList"
-                            :currentDate="state.currentDate"
-                            :uncompleted="
-                              formatDot(
-                                state.itemDateList[state.currentDate]
-                              ) != 1
-                            "
-                            @success="
-                              () => {
-                                emits('success');
-                                getList();
-                              }
-                            "
-                          />
-                        </KeepAlive>
-                      </template>
-                      <template v-else>
-                        <el-empty
-                          :description="`${state.date}月暂无待办事项`"
-                        />
-                      </template>
-                    </el-scrollbar>
-                  </template>
-                  <div
-                    class="absolute left-0 bottom-0 w-full text-right border border-gray-100 py-4 px-2"
-                    v-if="curMenu == 'NewTodoItems'"
-                  >
-                    <el-button type="primary" @click="onSave('add')"
-                      >保存事项</el-button
-                    >
-                  </div>
-                </el-col>
-              </el-row>
-            </div>
-          </div>
-        </el-card>
-      </template>
-    </el-dialog>
-    <ComponentDialogBacklogCheckbox
-      v-model:show="state.visibleBacklogHandle"
-      :date="state.time"
-      :type="props.type"
-      @success="
-        () => {
-          emits('success');
-          getList();
-        }
-      "
-    />
-    <!-- <el-dialog
-      title="确定要添加这个事项吗?"
-      v-model="visibleConfirm"
-      width="20%"
-    >
-      <div class="px-5">
-        <div class="flex justify-between mb-4">
-          <el-button type="danger" @click="onSave('add')"
-            >确定并继续添加待办事项</el-button
-          >
-          <el-button type="primary" @click="onSave('view')"
-            >确定并查看待办事项</el-button
-          >
-        </div>
-        <el-button type="" class="w-full" @click="visibleConfirm = false"
-          >取消</el-button
-        >
-      </div>
-    </el-dialog> -->
-  </div>
-</template>
-<script setup>
-import { request } from "@/utils";
-import moment from "moment";
-import { ArrowRight } from "@element-plus/icons-vue";
-import {
-  ref,
-  computed,
-  defineProps,
-  defineEmits,
-  watch,
-  reactive,
-  defineAsyncComponent,
-  nextTick
-} from "vue";
-import { hasAuth } from "@/router/utils";
-
-import ComponentDialogBacklogCheckbox from "./DialogBacklogCheckbox.vue";
-import ComponentProfileCard from "./ProfileCard.vue";
-import BacklogConfigList from "./BacklogConfigList.vue";
-// import CurrentMonthTodoItems from "./CurrentMonthTodoItems.vue";
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-import { ElMessage } from "element-plus";
-
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  type: {
-    type: String,
-    default: "edit"
-  },
-  complateTime: {
-    type: String,
-    default: ""
-  }
-});
-const emits = defineEmits(["update:show", "success", "onClickDay"]);
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-const cmpsRef = ref();
-
-const curMenu = ref("HandleMonthTodo");
-const currentMonthTodoItems = defineAsyncComponent(() =>
-  import("./CurrentMonthTodoItems.vue")
-);
-const itemStatusList = [
-  {
-    key: "待完成",
-    value: 0,
-    color: "bg-red-500"
-  },
-  {
-    key: "已完成",
-    value: 1,
-    color: "bg-green-600"
-  },
-  {
-    key: "部分完成",
-    value: 2,
-    color: "bg-blue-600"
-  }
-];
-
-const itemTypeList = ref([
-  {
-    key: "复查",
-    value: 1
-  },
-  {
-    key: "随访",
-    value: 2
-  },
-  {
-    key: "日常监测",
-    value: 3
-  },
-
-  {
-    key: "其他",
-    value: 0
-  }
-
-  // {
-  //   key: "检查",
-  //   value: 4
-  // },
-
-  // {
-  //   key: "回访",
-  //   value: 5
-  // }
-]);
-const cmps = {
-  0: defineAsyncComponent(() => import("./TodoItemOther.vue")), // 其他
-  1: defineAsyncComponent(() => import("./TodoItemCheck.vue")), // 复查
-  2: defineAsyncComponent(() => import("./TodoItemFollowUp.vue")), // 随访
-  3: defineAsyncComponent(() => import("./TodoItemMonitor.vue")), // 监测
-  4: defineAsyncComponent(() => import("./TodoItemInspect.vue")), // 检查
-  5: defineAsyncComponent(() => import("./TodoItemReturnVisit.vue")) // 回访
-};
-const calendarRef = ref();
-const menus = [
-  {
-    label: "新增待办事项",
-    key: "NewTodoItems",
-    auth: "headlthManage:todoList:edit"
-  },
-  {
-    label: "待办事项管理",
-    key: "TodoManagement",
-    auth: "headlthManage:todoList:edit"
-  },
-  {
-    label: "本月待办处理",
-    key: "HandleMonthTodo",
-    auth: ""
-  }
-];
-const state = reactive({
-  date: moment().format("YYYY-MM"),
-  calendarValue: "",
-  visibleBacklogHandle: false,
-  time: "",
-  itemList: {},
-  itemDateList: [],
-  itemType: 1, // 事项类别
-  todoDurationList: [],
-  currentDate: moment().format("YYYY-MM-DD")
-});
-const visibleConfirm = ref(false);
-const BacklogConfigListRef = ref();
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      initData();
-    }
-  }
-);
-const scrollToAnchor = data => {
-  // 从完整路径中解析出真正的锚点部分
-  const hash = data; // 注意:根据你的URL结构调整索引
-  if (hash) {
-    const element = document.getElementById(hash);
-    if (element) {
-      element.scrollIntoView({ behavior: "smooth" });
-    }
-  }
-};
-
-const onLiclick = hash => {
-  curMenu.value = "HandleMonthTodo";
-  nextTick(() => {
-    scrollToAnchor(hash);
-  });
-  // setTimeout(() => {
-  // }, 1000);
-  state.currentDate = hash;
-};
-const formatDot = data => {
-  if (!data) return;
-  const doneList = data.filter(v => v.done);
-  switch (doneList.length) {
-    case 0:
-      return 0;
-    case data.length:
-      return 1;
-    default:
-      return 2;
-  }
-};
-// 计算该月份的天数
-const getDaysInMonth = yearMonth => {
-  return moment(yearMonth, "YYYY-MM").endOf("month").date();
-};
-
-const handleChangeCurMenu = key => {
-  curMenu.value = key;
-  cmpsRef.value?.onReset();
-};
-const getList = () => {
-  return new Promise(resolve => {
-    request
-      .get("dataService/schedule/todoList/duration", {
-        params: {
-          archiveId: currentArchiveId.value,
-          startDate: state.date + "-01",
-          endDate: `${state.date}-${getDaysInMonth(state.date)}`,
-          filter: 1
-        }
-      })
-      .then(resp => {
-        const itemObj = {};
-        const data = resp.data;
-        state.todoDurationList = data;
-
-        data.map(v => {
-          itemObj[v.date] = v.schedules;
-        });
-        state.itemDateList = itemObj;
-        resolve();
-      });
-  });
-};
-const handleMonth = date => {
-  if (!date) return;
-  state.calendarValue = date;
-  getList();
-};
-const handleBackToday = async () => {
-  calendarRef.value.selectDate("today");
-  const time = moment().format("YYYY-MM-DD");
-  state.currentDate = time;
-  state.date = moment().format("YYYY-MM");
-  await getList();
-  onLiclick(time);
-};
-const onSave = () => {
-  cmpsRef.value.onSubmit(params => {
-    request
-      .post("/dataService/schedule", {
-        archiveId: currentArchiveId.value,
-        type: state.itemType,
-        ...params
-      })
-      .then(resp => {
-        ElMessage.success(resp.message);
-        cmpsRef.value.onReset();
-        visibleConfirm.value = false;
-        getList();
-        // if (key == "view") {
-        //   curMenu.value = "TodoManagement";
-        //   BacklogConfigListRef.value.initData();
-        // }
-        // visibleConfirm.value = false;
-      });
-  });
-};
-const formatDateToYearMonth = dateString => {
-  return moment(dateString).format("YYYY-MM");
-};
-const initData = async () => {
-  // 如果有值的话 说明是事项处理
-  if (props.complateTime) {
-    curMenu.value = "HandleMonthTodo";
-    state.date = formatDateToYearMonth(props.complateTime);
-    state.calendarValue = state.dete;
-    await getList();
-    setTimeout(() => {
-      onLiclick(props.complateTime);
-    }, 500);
-  } else {
-    curMenu.value = "HandleMonthTodo";
-    await getList();
-  }
-};
-</script>
-<style lang="scss" scoped>
-::v-deep .el-calendar__button-group {
-  display: none;
-}
-::v-deep .el-calendar-table .el-calendar-day {
-  text-align: center;
-}
-.item-card {
-  height: 100%;
-}
-::v-deep .el-calendar-table .el-calendar-day {
-  height: 50px;
-  // padding: 10px;
-}
-::v-deep .el-calendar__body {
-  padding: 10px !important;
-}
-::v-deep .el-calendar__header {
-  display: none;
-}
-::v-deep .el-dialog__header {
-  padding: 0px !important;
-}
-::v-deep .el-dialog__body {
-  padding: 0px;
-  overflow: hidden;
-}
-</style>

+ 0 - 417
src/views/healthManagement/components/DialogBacklogCheckbox.vue

@@ -1,417 +0,0 @@
-<template>
-  <div>
-    <el-dialog title="待办事项" append-to-body v-model="dialogVisible">
-      <div>
-        <el-card>
-          <template #header>
-            <div class="flex items-center justify-between">
-              <div>
-                {{ props.date }} {{ getWeek(props.date) }}
-                <span style="color: #e6a23c"
-                  >温馨提示:您通过勾选或者取消勾选来标记事项的完成情况</span
-                >
-              </div>
-              <div v-if="isEdit">
-                <el-button
-                  type="primary"
-                  @click="handleAddItem"
-                  :disabled="isFormerly"
-                  >新增事项
-                </el-button>
-                <el-button type="primary" @click="handleBack"
-                  >返回日历</el-button
-                >
-              </div>
-            </div>
-          </template>
-          <div v-if="state.todoList?.length">
-            <div
-              v-for="item in state.todoList"
-              :key="item.id"
-              class="bg-slate-100 mb-2 relative px-2 py-3 flex items-center justify-between w-full"
-            >
-              <div class="flex w-full">
-                <el-button
-                  type="primary"
-                  class="absolute top-3 right-1"
-                  link
-                  @click="handleEditRemark(item)"
-                  >完成情况备注</el-button
-                >
-                <div @click="handleDone(item)" class="flex">
-                  <el-icon
-                    v-if="item.done"
-                    style="color: #67c23a; font-size: 20px"
-                    class="mr-2"
-                    ><SuccessFilled
-                  /></el-icon>
-                  <el-icon v-else style="font-size: 20px" class="mr-2"
-                    ><CircleCheck
-                  /></el-icon>
-                </div>
-                <div class="w-9/12">
-                  <el-text :tag="item.done ? 'del' : 'span'">
-                    <template v-if="item.type == 2">
-                      <el-text tag="b">{{ item.name }}回访</el-text>
-                      <div class="mb-2" />
-                      <el-text size="small" type="info"
-                        >回访时需要填写:{{ item.content }}</el-text
-                      >
-                      <div />
-                    </template>
-
-                    <template v-else-if="item.type == 0">
-                      <el-text tag="b">{{ item.name }}</el-text>
-                      <div class="mb-2" />
-                      <el-text size="small" type="info"
-                        >检查需包含:{{ item.content }}</el-text
-                      >
-                    </template>
-                    <template v-else>
-                      <el-text tag="b">{{ item.content }}</el-text>
-                    </template>
-                    <div />
-                    <div class="mb-2" />
-
-                    <el-text size="small" type="info"
-                      >备注:{{ item.remark || "-" }}</el-text
-                    >
-                  </el-text>
-                  <!-- <div class="mt-2">
-                    <el-input
-                      v-model="item.comment"
-                      placeholder="选填,输入事项完成备注信息"
-                      :autosize="{ minRows: 3, maxRows: 6 }"
-                      type="textarea"
-                    ></el-input>
-                  </div> -->
-                </div>
-              </div>
-              <div class="flex items-center">
-                <!-- <el-popconfirm
-                  title="确定要删除此待办事项吗?"
-                  @confirm="handleDelete(item.id)"
-                >
-                  <template #reference>
-                    <el-button type="primary" link style="color: red">删除</el-button>
-                  </template>
-                </el-popconfirm> -->
-
-                <el-popconfirm
-                  @confirm="handleDelete(item)"
-                  title="确定要删除这个事项吗?删除后不可恢复?"
-                >
-                  <template #reference>
-                    <el-button
-                      type="primary"
-                      link
-                      style="color: red"
-                      class="ml-5"
-                      v-if="isEdit"
-                      >删除</el-button
-                    >
-                  </template>
-                </el-popconfirm>
-              </div>
-            </div>
-          </div>
-          <div v-else>
-            <el-empty />
-          </div>
-        </el-card>
-        <el-dialog v-model="state.visibleDelete" width="30%">
-          <div>
-            <el-text tag="b" class="mt-2 mb-2"
-              >请选择删除内容,删除后不可数据不可恢复:</el-text
-            >
-            <div
-              class="bg-slate-100 mt-2 mb-2 p-2 flex items-center"
-              @click="() => (state.currentDeleteItem = 0)"
-            >
-              <el-icon
-                v-if="state.currentDeleteItem == 0"
-                style="font-size: 20px; color: #67c23a"
-                class="mr-2"
-                ><SuccessFilled
-              /></el-icon>
-              <span v-else class="dot mr-2" />
-              <div>
-                <div>
-                  {{ props.date }}
-                  <span v-if="props.date == state.currentItem.endDate"
-                    >(当天)</span
-                  >
-                  <div>{{ state.currentItem.content }}</div>
-                </div>
-              </div>
-            </div>
-
-            <div
-              class="bg-slate-100 mb-2 p-2 flex items-center"
-              @click="() => (state.currentDeleteItem = 1)"
-            >
-              <el-icon
-                v-if="state.currentDeleteItem == 1"
-                style="font-size: 20px; color: #67c23a"
-                class="mr-2"
-                ><SuccessFilled
-              /></el-icon>
-              <span class="dot mr-2" v-else />
-              <div>
-                <div>
-                  {{ props.date }} 至
-                  {{ state.currentItem?.endDate }}
-
-                  <span v-if="props.date == state.currentItem.endDate"
-                    >(当天)</span
-                  >
-                  <span v-else> (当天起至往后)</span>
-                </div>
-                <div>
-                  每{{ ["天", "周", "月", "天"][state.currentItem?.type || 0]
-                  }}{{ state.currentItem.content }}
-                </div>
-              </div>
-            </div>
-
-            <div
-              class="bg-slate-100 mb-2 p-2 flex items-center"
-              @click="() => (state.currentDeleteItem = 2)"
-            >
-              <el-icon
-                v-if="state.currentDeleteItem == 2"
-                style="font-size: 20px; color: #67c23a"
-                class="mr-2"
-                ><SuccessFilled
-              /></el-icon>
-              <span class="dot mr-2" v-else />
-              <div>
-                <div>
-                  {{ state.currentItem?.startDate }} 至
-                  {{ state.currentItem?.endDate }} (所有时间)
-                </div>
-                <div>
-                  每{{ ["天", "周", "月", "天"][state.currentItem?.type]
-                  }}{{ state.currentItem.content }}
-                </div>
-              </div>
-            </div>
-            <div class="text-right">
-              <el-button @click="() => (state.visibleDelete = false)"
-                >取消</el-button
-              >
-              <el-popconfirm
-                @confirm="handleDeleteItem(index)"
-                title="确定要删除这个事项吗?删除后不可恢复?"
-              >
-                <template #reference>
-                  <el-button type="primary">确定</el-button>
-                </template>
-              </el-popconfirm>
-            </div>
-          </div>
-          <div />
-        </el-dialog>
-      </div>
-    </el-dialog>
-    <ComponentDialogSetMatter
-      v-model:show="state.visibleTable"
-      :date="props.date"
-      @save="onSave"
-    />
-    <el-dialog
-      append-to-body
-      title="完成情况备注"
-      v-model="state.visibleRemark"
-    >
-      <div class="mt-2">
-        <el-input
-          v-model="state.rowData.comment"
-          placeholder="选填,输入事项完成备注信息"
-          :autosize="{ minRows: 6, maxRows: 10 }"
-          type="textarea"
-        />
-      </div>
-      <template #footer>
-        <el-button type="primary" plain @click="state.visibleRemark = false"
-          >取消</el-button
-        >
-        <el-button type="primary" @click="onSaveRemark()">确定</el-button>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request, getWeek } from "@/utils";
-
-import { ref, computed, defineProps, defineEmits, watch, reactive } from "vue";
-import { SuccessFilled, CircleCheck } from "@element-plus/icons-vue";
-import ComponentDialogSetMatter from "./DialogSetMatter.vue";
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-import { ElMessage } from "element-plus";
-import moment from "moment";
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  date: {
-    type: String,
-    default: ""
-  },
-  rowData: {
-    type: Object,
-    default: () => {}
-  },
-  type: {
-    type: String,
-    default: "edit"
-  }
-});
-const emits = defineEmits(["update:show", "success"]);
-const isEdit = computed(() => {
-  return props.type == "edit";
-});
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      getTodoList();
-    } else {
-    }
-  }
-);
-
-// 是否过了今日的时间
-const isFormerly = computed(() => {
-  return moment(props.date).diff(moment(), "days") < 0;
-});
-
-const state = reactive({
-  visibleTable: false,
-  todoList: [],
-  currentItem: [],
-  currentDeleteItem: 0,
-  visibleDelete: false,
-  visibleRemark: false,
-  rowData: {
-    comment: ""
-  }
-});
-const handleAddItem = () => {
-  state.visibleTable = true;
-};
-const handleEditRemark = item => {
-  state.rowData = item;
-  state.visibleRemark = true;
-};
-const onSave = tableData => {
-  const params = tableData.map(v => {
-    return {
-      ...v,
-      archiveId: currentArchiveId.value,
-      duration: Number(v.duration),
-      date: props.date
-    };
-  });
-  request
-    .post("/platformApi/dataService/diseaseManage/todos", {
-      todos: params
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      dialogVisible.value = false;
-      emits("success");
-    });
-};
-const getTodoList = () => {
-  request
-    .get("/platformApi/dataService/diseaseManage/todoList/duration", {
-      params: {
-        archiveId: currentArchiveId.value,
-        startDate: props.date,
-        endDate: props.date
-      }
-    })
-    .then(resp => {
-      state.todoList = resp.data[0]?.checkItems?.map(v => {
-        return {
-          visible: false,
-          comment: "",
-          ...v
-        };
-      });
-    });
-};
-const handleDone = item => {
-  request
-    .post("/platformApi/dataService/diseaseManage/checkTodo", {
-      id: item.id,
-      date: props.date,
-      status: item.done ? 0 : 1
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      getTodoList();
-      emits("success");
-    });
-};
-const handleDelete = item => {
-  state.currentDeleteItem = 0; //恢复默认值
-  state.currentItem = item;
-  // state.visibleDelete = true;
-  handleDeleteItem();
-};
-const handleDeleteItem = index => {
-  request
-    .post("/platformApi/dataService/diseaseManage/delete/todo", {
-      id: state?.currentItem?.id,
-      date: props.date,
-      type: state.currentDeleteItem
-    })
-    .then(resp => {
-      getTodoList();
-      // state.todoList[index] = false;
-      ElMessage.success(resp?.message);
-      emits("success");
-      // state.visibleDelete = false;
-    });
-};
-const onSaveRemark = () => {
-  const item = state.rowData;
-  request
-    .post("/platformApi/dataService/diseaseManage/todo/comment", {
-      id: item.id,
-      date: props.date,
-      comment: item.comment
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      getTodoList();
-      state.visibleRemark = false;
-    });
-};
-const handleBack = () => {
-  dialogVisible.value = false;
-};
-</script>
-<style scoped lang="scss">
-.dot {
-  width: 20px;
-  height: 20px;
-  border: 1px solid #ddd;
-  border-radius: 50%;
-}
-</style>

+ 0 - 371
src/views/healthManagement/components/DialogCurrentMonthBacklog.vue

@@ -1,371 +0,0 @@
-<template>
-  <div>
-    <el-dialog title="" v-model="dialogVisible" :show-close="false" fullscreen>
-      <template #header>
-        <ComponentTodoList></ComponentTodoList>
-        <!-- <el-card>
-          <div>
-            <el-row :gutter="10">
-              <el-col :span="16" class="flex items-center">
-                事项期望完成时间:
-                <el-date-picker
-                  v-model="state.query.times"
-                  type="daterange"
-                  range-separator="-"
-                  start-placeholder="开始时间"
-                  end-placeholder="完成时间"
-                  value-format="YYYY-MM-DD"
-                  :clearable="false"
-                />
-                <el-select
-                  v-model="state.query.type"
-                  placeholder="全部事项类型"
-                  filterable
-                  class="ml-2"
-                >
-                  <el-option label="全部事项类型" :value="-1"></el-option>
-                  <el-option
-                    v-for="item in state.typeList"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  >
-                  </el-option>
-                </el-select>
-                <el-select
-                  v-model="state.query.type"
-                  placeholder="全部完成状态"
-                  filterable
-                  class="ml-2"
-                >
-                  <el-option label="全部状态" :value="-1"></el-option>
-                  <el-option
-                    v-for="item in state.statusList"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  >
-                  </el-option>
-                </el-select>
-              </el-col>
-              <el-col :span="8">
-                <div class="ml-2 flex items-center text-right">
-                  <el-input
-                    v-model="state.query.value"
-                    placeholder="请输入"
-                    class="input-with-select"
-                    clearable
-                  >
-                    <template #prepend>
-                      <el-select
-                        v-model="state.query.key"
-                        placeholder="请选择"
-                        style="width: 115px"
-                        clearable
-                      >
-                        <el-option label="档案号" value="archive_id" />
-                        <el-option label="姓名" value="name" />
-                      </el-select>
-                    </template>
-                    <template #append>
-                      <el-button :icon="Search" @click="onSearch"
-                        >查询</el-button
-                      >
-                    </template>
-                  </el-input>
-                  <el-button
-                    class="ml-10"
-                    type="danger"
-                    plain
-                    @click="dialogVisible = false"
-                    >关闭</el-button
-                  >
-                </div>
-              </el-col>
-            </el-row>
-          </div>
-        </el-card>
-        <el-card shadow="never" class="mt-4">
-          <div>
-            <el-table
-              :data="state.tableData"
-              style="width: 100%"
-              :span-method="objectSpanMethod"
-              border
-            >
-              <el-table-column prop="sn" label="档案号" width="100">
-              </el-table-column>
-              <el-table-column prop="name" label="姓名"> </el-table-column>
-              <el-table-column prop="gender" label="性别" width="60">
-              </el-table-column>
-              <el-table-column prop="age" label="年龄" width="60">
-              </el-table-column>
-              <el-table-column label="待办事项类型">
-                <template #default="{ row }">
-                  {{ state.constType[row.todoInfo?.type] }}
-                </template>
-              </el-table-column>
-              <el-table-column label="待办事项内容">
-                <template #default="{ row }">
-                  {{ row.todoInfo?.content }}
-                </template>
-              </el-table-column>
-              <el-table-column label="任务期望完成时间">
-                <template #default="{ row }">
-                  <div class="flex items-center">
-                    {{ row.todoInfo?.startDate }} 至 {{ row.todoInfo?.endDate }}
-                    <el-tag>{{
-                      state.frequencyType[row.todoInfo?.frequencyType]
-                    }}</el-tag>
-                  </div>
-                </template>
-              </el-table-column>
-              <el-table-column label="事项完成情况">
-                <template #default="{ row }">
-                  <div
-                    v-for="item in row.todoInfo?.status"
-                    :key="item.id"
-                    class="flex items-center"
-                  >
-                    {{ item }}
-                    <div v-if="row.todoInfo?.status.length == 1" class="pl-2">
-                      <el-tag
-                        v-if="!timeDiffer(row?.todoInfo?.endDate)"
-                        type="success"
-                        >今天</el-tag
-                      >
-                      <el-tag
-                        v-if="timeDiffer(row?.todoInfo?.endDate) < 0"
-                        type="danger"
-                        >超时{{
-                          Number(0 - timeDiffer(row?.todoInfo?.endDate))
-                        }}天</el-tag
-                      ><el-tag v-else
-                        >{{ timeDiffer(row?.todoInfo?.endDate) }}天后</el-tag
-                      >
-                    </div>
-                  </div>
-                </template>
-              </el-table-column>
-              <el-table-column prop="age" label="操作">
-                <template #default="{ row }">
-                  <el-button type="primary" link @click="handleBacklog(row)"
-                    >事项日历</el-button
-                  >
-                  <el-button type="primary" link @click="handleManage(row)"
-                    >管理</el-button
-                  >
-                </template>
-              </el-table-column>
-            </el-table>
-
-            <el-pagination
-              class="justify-end mt-4"
-              :current-page="state.query.page"
-              :page-size="state.query.pageSize"
-              :total="state.total"
-              background
-              layout="total, prev, pager, next, jumper"
-              @current-change="
-                page => {
-                  state.query.page = page;
-                  getList();
-                }
-              "
-            ></el-pagination>
-          </div>
-        </el-card> -->
-      </template>
-
-      <!-- <ComponentDialogBacklog
-        v-model:show="state.visibleBacklog"
-        type="preview"
-      ></ComponentDialogBacklog> -->
-    </el-dialog>
-  </div>
-</template>
-<script lang="ts" setup>
-import { ref, reactive, computed, defineProps, defineEmits, watch } from "vue";
-import { Search, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-import { useRouter, useRoute } from "vue-router";
-import { request, timeDiffer } from "@/utils";
-const [route, router] = [useRoute(), useRouter()];
-import moment from "moment";
-import ComponentDialogBacklog from "./DialogBacklog.vue";
-import ComponentTodoList from "../todoList.vue";
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  }
-});
-const state = reactive({
-  query: {
-    page: 1,
-    pageSize: 15,
-    times: [
-      moment().startOf("month").format("YYYY-MM-DD"),
-      moment().endOf("month").format("YYYY-MM-DD")
-    ],
-    value: "",
-    key: "",
-    type: -1,
-    status: -1
-  },
-  total: 0,
-  tableData: [],
-  constType: ["检查", "其他事项", "回访"],
-  frequencyType: ["每天事项", "每周事项", "每月事项", "指定日期事项"],
-  typeList: [
-    {
-      label: "检查",
-      value: 0
-    },
-    {
-      label: "回访",
-      value: 2
-    },
-    {
-      label: "其他事项",
-      value: 1
-    }
-  ],
-  statusList: {
-    0: {
-      label: "已完成",
-      value: 0
-    },
-    1: {
-      label: "待完成",
-      value: 0
-    },
-
-    2: {
-      label: "未完成",
-      value: 0
-    }
-  },
-  visibleBacklog: false
-});
-const mergeArr = ["sn", "name", "gender", "age"];
-const mergeObj = {};
-const emits = defineEmits(["update:show"]);
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      initData();
-    } else {
-    }
-  }
-);
-const getSpanArr = data => {
-  mergeArr.forEach((key, index1) => {
-    let count = 0; // 用来记录需要合并行的起始位置
-    mergeObj[key] = []; // 记录每一列的合并信息
-    data.forEach((item, index) => {
-      // index == 0表示数据为第一行,直接 push 一个 1
-      if (index === 0) {
-        mergeObj[key].push(1);
-      } else {
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
-        if (
-          item[key] === data[index - 1][key] &&
-          item["sn"] === data[index - 1]["sn"]
-        ) {
-          mergeObj[key][count] += 1;
-          mergeObj[key].push(0);
-        } else {
-          // 如果当前行和上一行其值不相等
-          count = index; // 记录当前位置
-          mergeObj[key].push(1); // 重新push 一个 1
-        }
-      }
-    });
-  });
-};
-// 默认接受四个值 { 当前行的值, 当前列的值, 行的下标, 列的下标 }
-const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
-  // 判断列的属性
-  if (mergeArr.indexOf(column.property) !== -1) {
-    // 判断其值是不是为0
-    if (mergeObj[column.property][rowIndex]) {
-      return [mergeObj[column.property][rowIndex], 1];
-    } else {
-      // 如果为0则为需要合并的行
-      return [0, 0];
-    }
-  }
-};
-
-const transformData = data => {
-  const transformedData = [];
-
-  data.forEach(item => {
-    if (item.todoStatistics.length) {
-      item.todoStatistics.forEach((info, index) => {
-        transformedData.push({
-          ...item,
-          todoInfo: info
-        });
-      });
-    } else {
-      transformedData.push({
-        ...item,
-        todoInfo: {}
-      });
-    }
-  });
-  return transformedData;
-};
-
-const getList = () => {
-  if (!state.query?.times.length) return;
-  let [startDate, endDate] = state.query.times;
-  request
-    .get("/platformApi/dataService/diseaseManage/archives/todoDuration", {
-      params: {
-        startDate,
-        endDate,
-        type: state.query.type,
-        status: state.query.status,
-        key: state.query.key,
-        value: state.query.value,
-        page: state.query.page,
-        pageSize: state.query.pageSize
-      }
-    })
-    .then(resp => {
-      state.tableData = transformData(resp?.data?.list);
-      state.total = resp?.data?.total;
-      getSpanArr(state.tableData);
-    });
-};
-const initData = () => {
-  getList();
-};
-const onSearch = () => {
-  state.query.page = 1;
-  getList();
-};
-const handleBacklog = row => {
-  state.visibleBacklog = true;
-  useManageProject.SET_CURRENT_ARCHIVES(row.sn);
-};
-const handleManage = row => {
-  router.push(
-    `/healthManagement/plan/detail?archivesId=${row.sn}&type=DiseaseVisit`
-  );
-};
-</script>

+ 0 - 147
src/views/healthManagement/components/DialogEditTags.vue

@@ -1,147 +0,0 @@
-<template>
-  <div>
-    <el-dialog title="设置标签" v-model="dialogVisible" height="50vh">
-      <div>
-        <el-space wrap>
-          <el-select
-            v-model="selectTags"
-            placeholder="请选择标签"
-            filterable
-            clearable
-            style="width: 400px"
-            multiple
-          >
-            <el-option
-              v-for="item in tags"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            >
-              <template #default>
-                <div>
-                  <span style="font-weight: bold">{{ item.name }} </span>
-                  <div class="text-sm" v-if="item.purpose">
-                    用途:{{ item.purpose }}
-                  </div>
-                </div>
-              </template>
-            </el-option>
-          </el-select>
-          <el-button type="primary" @click="handleAddTags">确认</el-button>
-        </el-space>
-        <el-divider />
-        <div class="w-full" style="height: 300px">
-          <h4 class="mb-4">已设置标签</h4>
-          <el-space wrap v-if="setTags?.length">
-            <el-tag
-              v-for="(tag, index) in setTags"
-              :key="tag.id"
-              closable
-              @close="handleRemoveTag(index)"
-              >{{ tag.name }}</el-tag
-            >
-          </el-space>
-          <div v-else class="text-center">
-            <el-empty description="暂未设置标签" />
-          </div>
-        </div>
-      </div>
-      <template #footer>
-        <div>
-          <el-button @click="dialogVisible = false">取 消</el-button>
-          <el-button type="primary" @click="onSubmit">保 存</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request, unique } from "@/utils";
-import { ElMessage } from "element-plus";
-import { ref, computed, defineProps, defineEmits, watch } from "vue";
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  id: {
-    type: String,
-    default: ""
-  }
-});
-const emits = defineEmits(["update:show", "success"]);
-const tags = ref([]);
-const selectTags = ref([]);
-const setTags = ref([]);
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      initData();
-    } else {
-    }
-  }
-);
-const getArchiveTags = () => {
-  if (!props.id) return;
-  request
-    .get(`dataService/schemeManage/tag/archive?archiveId=${props.id}`)
-    .then(resp => {
-      setTags.value = resp.data || [];
-    });
-};
-const getTags = () => {
-  request
-    .get(`dataService/schemeManage/tag/paginate?pageSize=${9999}`)
-    .then(resp => {
-      tags.value = resp.data.list;
-    });
-};
-const handleAddTags = () => {
-  if (!selectTags?.value.length) {
-    return ElMessage.error("请至少选择一个标签");
-  }
-  const _setTags = tags.value?.filter(v => selectTags.value?.includes(v.id));
-  setTags.value = unique([...setTags.value, ..._setTags], "id");
-  selectTags.value = [];
-};
-const handleRemoveTag = index => {
-  setTags.value?.splice(index, 1);
-};
-const onSubmit = () => {
-  if (!setTags?.value.length) {
-    return ElMessage.error("请至少选择一个标签");
-  }
-  request
-    .post(`dataService/schemeManage/tag/archive`, {
-      archiveId: props.id,
-      tagIds: setTags.value?.map(v => v.id)
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      emits("success");
-      dialogVisible.value = false;
-    });
-};
-const initData = () => {
-  selectTags.value = [];
-  getArchiveTags();
-  getTags();
-};
-</script>
-<style lang="scss" scoped>
-.el-select-dropdown__item {
-  // color: var(--gray-Alpha-white-1200, rgba(255, 255, 255, 0.85)) !important;
-  overflow: auto;
-  height: auto;
-}
-</style>

+ 0 - 230
src/views/healthManagement/components/DialogHealthManageEvaluationHistory.vue

@@ -1,230 +0,0 @@
-<template>
-  <div class="p-4">
-    <div v-if="props.list.length">
-      <div class="bg-white h-64 rounded shadow">
-        <Chart ref="chartRef" />
-      </div>
-      <div class="flex mt-4 w-full space-x-4">
-        <div class="bg-white rounded shadow p-1">
-          <div
-            v-for="(item, index) in historyList"
-            :key="index"
-            class="cursor-pointer hover:bg-gray-50 flex items-center justify-between space-x-4 p-2 py-3 last:border-b-0 border-b border-solid border-gray-100"
-            :class="{
-              'text-blue-500': currentHistory == index,
-              'text-gray-500': currentHistory != index
-            }"
-            @click="currentHistory = index"
-          >
-            <span class="font-bold">
-              {{
-                index == historyList.length - 1
-                  ? "以前"
-                  : historyList[
-                      index - 1 > 0 ? index - 1 : 0
-                    ]?.createdAt?.split(" ")[0]
-              }}
-              至
-              {{ item.createdAt?.split(" ")[0] }}
-            </span>
-            <div class="flex items-center">
-              <span class="">评估记录</span>
-              <ArrowRight class="w-4" />
-            </div>
-          </div>
-        </div>
-        <div class="bg-white rounded shadow p-4 flex-1 space-y-4">
-          <div>
-            <div class="font-bold text-base">管理评估对应时间段:</div>
-            <div>
-              {{
-                currentHistory == historyList.length - 1
-                  ? "以前"
-                  : historyList[
-                      currentHistory - 1 > 0 ? currentHistory - 1 : 0
-                    ]?.createdAt?.split(" ")[0]
-              }}
-              至
-              {{ historyList[currentHistory].createdAt?.split(" ")[0] }}
-            </div>
-          </div>
-          <div
-            v-if="
-              currentHistory !== historyList.length - 1 &&
-              historyList[currentHistory]?.etiologies?.length
-            "
-          >
-            <div class="font-bold text-base">期间对应的病因:</div>
-            <el-tag
-              v-for="(tag, tagIdx) in historyList[currentHistory + 1]
-                .etiologies"
-              :key="tagIdx"
-              size="large"
-              type="danger"
-              class="m-1"
-              >{{ tag.label }}</el-tag
-            >
-          </div>
-          <div>
-            <div class="font-bold text-base">健康综合评分:</div>
-            <el-tag size="large" class="m-1"
-              >{{ historyList[currentHistory]?.score }}分</el-tag
-            >
-          </div>
-          <template v-if="currentHistory !== historyList.length - 1">
-            <div>
-              <div class="font-bold text-base">期间期望达成的效果:</div>
-              <div class="p-2 bg-gray-50 rounded">
-                <div v-html="historyList[currentHistory + 1]?.target"></div>
-              </div>
-            </div>
-            <div class="space-y-4">
-              <div class="font-bold text-base">期间执行的个性化干预方案:</div>
-              <div
-                v-for="(child, childIdx) in historyList[currentHistory + 1]
-                  .personalizeInterventions"
-                :key="childIdx"
-              >
-                <template v-if="child.content">
-                  <div class="font-bold">{{ child.title }}:</div>
-                  <div class="p-2 bg-gray-50 rounded">
-                    <div v-html="child.content"></div>
-                  </div>
-                </template>
-              </div>
-            </div>
-            <div>
-              <div class="font-bold text-base">需要进一步检查:</div>
-              <div class="p-2 bg-gray-50 rounded">
-                <el-table :data="historyList[currentHistory + 1]?.furtherInfo">
-                  <el-table-column
-                    label="检查项目"
-                    prop="label"
-                    width="200"
-                  ></el-table-column>
-                  <el-table-column
-                    label="检查意义"
-                    prop="tip"
-                  ></el-table-column>
-                </el-table>
-              </div>
-            </div>
-          </template>
-        </div>
-      </div>
-    </div>
-    <div v-else>
-      <el-empty description="暂无评估历史"></el-empty>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  ref,
-  reactive,
-  inject,
-  onActivated,
-  onMounted,
-  defineAsyncComponent,
-  defineProps,
-  nextTick,
-  defineExpose
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { manageLevel } from "@/enums/managementPlan.ts";
-import {
-  CopyDocument,
-  Fold,
-  ArrowLeft,
-  ArrowRight
-} from "@element-plus/icons-vue";
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-
-import { request, formateArchivesModuleValue, deepClone } from "@/utils";
-import Chart from "@/components/Chart.vue";
-
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const props = defineProps({
-  list: {
-    type: Array
-  }
-});
-const currentHistory = ref(0);
-const historyList = computed(() => {
-  let arr = props.list;
-  console.log(arr, "历史数据");
-  return arr;
-});
-const chartRef = ref();
-
-const list = ref([]);
-
-const init = async () => {
-  chartRef?.value?.setOption({
-    title: {
-      text: "管理效果趋势",
-      top: "10",
-      left: "10"
-    },
-    grid: {
-      left: "5%",
-      right: "5%",
-      bottom: "15%"
-    },
-    // tooltip: {
-    //   trigger: "axis",
-    //   showContent: true
-    // },
-    xAxis: {
-      type: "category",
-      data: props.list.map(v => v.createdAt?.split(" ")[0]).reverse()
-    },
-    yAxis: {
-      type: "value",
-      axisLine: { show: false },
-      axisTick: { show: false },
-      axisLabel: { show: false }
-    },
-    series: [
-      {
-        data: props.list.map(v => Number(v.score)).reverse(),
-        type: "line",
-        label: {
-          show: true,
-          position: "top",
-          formatter: params => {
-            return `${params.value}分`;
-          }
-        },
-        smooth: true
-      }
-    ]
-  });
-};
-watch(
-  props.list,
-  (n, o) => {
-    nextTick(() => {
-      setTimeout(init, 1000);
-    });
-  },
-  { deep: true, immediate: true }
-);
-onMounted(() => {
-  // init();
-});
-
-defineExpose({
-  initChart: () => {
-    nextTick(init);
-  }
-});
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 47
src/views/healthManagement/components/DialogPreviewSuggest.vue

@@ -1,47 +0,0 @@
-<template>
-  <div>
-    <el-dialog title="查看健康建议" v-model="dialogVisible">
-      <template #header>
-        <h4>
-          {{ props.data.createdAt.split(" ")[0] }} 至
-          {{ props.data.nextTime.split(" ")[0] }}
-        </h4>
-      </template>
-      <div>
-        {{ props.data.advise }}
-      </div>
-      <template #footer> </template>
-    </el-dialog>
-  </div>
-</template>
-<script lang="ts" setup>
-import { ref, computed, defineProps, defineEmits, watch } from "vue";
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  data: {
-    type: Object,
-    default: () => {}
-  }
-});
-const emits = defineEmits(["update:show"]);
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-    } else {
-    }
-  }
-);
-</script>

+ 0 - 183
src/views/healthManagement/components/DialogSelectIllness.vue

@@ -1,183 +0,0 @@
-<template>
-  <div>
-    <el-dialog title="添加管理计划" v-model="dialogVisible">
-      <el-form ref="formRef" :model="form" label-width="180px">
-        <el-form-item
-          label="请选择管理级别:"
-          prop="level"
-          :rules="[
-            { required: true, message: '请选择管理级别', trigger: 'blur' }
-          ]"
-        >
-          <el-select
-            v-model="form.level"
-            filterable
-            placeholder="请选择管理级别"
-            class="w-full"
-            @change="form.selectValue = ''"
-          >
-            <el-option
-              v-for="item in state.levelList"
-              :key="item.id"
-              :label="`${item.title} (${item.scope} )`"
-              :value="item?.id"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item
-          label="请选择要管理的疾病:"
-          prop="selectValue"
-          :rules="[{ required: true, message: '请选择疾病', trigger: 'blur' }]"
-          v-if="[1, 2].includes(form.level)"
-        >
-          <el-select
-            v-model="form.selectValue"
-            filterable
-            placeholder=""
-            class="w-full"
-          >
-            <el-option
-              v-for="item in state.nodeList"
-              :key="item.id"
-              :label="item.properties?.name"
-              :value="item?.id"
-            />
-          </el-select>
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div>
-          <el-button @click="dialogVisible = false">取 消</el-button>
-          <el-button type="primary" @click="handleNext">确 定</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request } from "@/utils";
-import {
-  ref,
-  computed,
-  defineProps,
-  defineEmits,
-  watch,
-  reactive,
-  nextTick
-} from "vue";
-import { useRouter } from "vue-router";
-const [router] = [useRouter()];
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  nodeTag: {
-    type: String,
-    default: "可管理"
-  },
-  confirmFn: {
-    type: Function,
-    default: undefined
-  }
-});
-const emits = defineEmits(["update:show"]);
-
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-const state = reactive({
-  selectValue: "",
-  nodeList: [],
-  filterData: [],
-  levelList: []
-});
-const formRef = ref();
-const form = reactive({
-  selectValue: "",
-  level: ""
-});
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      initData();
-    } else {
-    }
-  }
-);
-const getNodeList = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 9999,
-        tag: props.nodeTag
-      }
-    })
-    .then(async resp => {
-      await getDetail();
-      const filterData = state.filterData?.map(v => v.disease);
-      state.nodeList = resp.data.list.filter(v => {
-        return !filterData.includes(v.properties?.name);
-      });
-    });
-};
-const getDetail = () => {
-  const url =
-    props.nodeTag == "功能医学管理"
-      ? `/dataService/healthManage/detail`
-      : "/dataService/diseaseManage/detail";
-  return new Promise(resolve => {
-    request
-      .get(url, {
-        params: {
-          archiveId: currentArchiveId.value
-        }
-      })
-      .then(resp => {
-        state.filterData = resp.data;
-        resolve();
-      });
-  });
-};
-const handleNext = () => {
-  const illness = state.nodeList?.find(v => form.selectValue == v.id);
-  formRef.value.validate(valid => {
-    if (!valid) return;
-
-    if (props.confirmFn) {
-      props.confirmFn(form.selectValue, illness.properties?.name, form.level);
-    } else {
-      router.push(
-        `/healthManagement/evaluate?illnessId=${form.selectValue || ""}&name=${
-          illness?.properties?.name || ""
-        }&archivesId=${currentArchiveId.value}&level=${form.level}`
-      );
-    }
-  });
-};
-
-const getLevelList = () => {
-  request.get("dataService/schemeManage/diseaseManageLevels").then(resp => {
-    state.levelList = resp.data;
-  });
-};
-const initData = () => {
-  nextTick(() => {
-    formRef.value.resetFields();
-  });
-  getNodeList();
-  getLevelList();
-};
-</script>

+ 0 - 126
src/views/healthManagement/components/DialogSetMatter.vue

@@ -1,126 +0,0 @@
-<template>
-  <div>
-    <el-dialog title="新增事项" v-model="dialogVisible" width="80%">
-      <div class="mb-3">
-        请选择事项类别:
-        <el-select v-model="state.itemType">
-          <el-option label="检查事项" :value="1"></el-option>
-          <el-option label="回访事项" :value="2"></el-option>
-          <el-option label="其他事项" :value="3"></el-option>
-        </el-select>
-      </div>
-      <div v-if="state.itemType == 1">
-        <ComponentSetCheckItem
-          ref="setCheckItemRef"
-          :tableData="state.checkItemTableData"
-          @add="handleAddCheckItemTable"
-          :date="props.date"
-        ></ComponentSetCheckItem>
-      </div>
-
-      <div class="mt-8" v-else-if="state.itemType == 2">
-        <ComponentSetRetrun
-          ref="setOtherReturnRef"
-          :tableData="state.returnItemTableData"
-          @add="handleAddReturnItemTable"
-          :date="props.date"
-        ></ComponentSetRetrun>
-      </div>
-      <div class="mt-8" v-else-if="state.itemType == 3">
-        <ComponentSetOtherItem
-          ref="setOtherItemRef"
-          :tableData="state.otherItemTableData"
-          @add="handleAddOtherItemTable"
-          :date="props.date"
-        ></ComponentSetOtherItem>
-      </div>
-      <template #footer>
-        <div>
-          <el-button @click="dialogVisible = false">取 消</el-button>
-          <el-button type="primary" @click="onSave">保存</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request } from "@/utils";
-import { ref, computed, defineProps, defineEmits, watch, reactive } from "vue";
-import ComponentSetCheckItem from "./SetCheckItem.vue";
-import ComponentSetOtherItem from "./SetOtherItem.vue";
-import ComponentSetRetrun from "./SetRetrun.vue";
-
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  },
-  date: {
-    type: String,
-    default: ""
-  }
-});
-const emits = defineEmits(["update:show", "save"]);
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-
-watch(
-  () => dialogVisible.value,
-  n => {
-    if (n) {
-      onReset();
-    } else {
-    }
-  }
-);
-const state = reactive({
-  checkItemTableData: [],
-  otherItemTableData: [],
-  returnItemTableData: [],
-  itemType: 1
-});
-const setCheckItemRef = ref();
-const setOtherItemRef = ref();
-const setOtherReturnRef = ref();
-const handleAddCheckItemTable = config => {
-  state.checkItemTableData.push(config);
-};
-
-const handleAddOtherItemTable = config => {
-  state.otherItemTableData.push(config);
-};
-const handleAddReturnItemTable = config => {
-  state.returnItemTableData.push(config);
-};
-const onSave = () => {
-  let tableData = [];
-  if (state.itemType == 1) {
-    tableData = state.checkItemTableData;
-  } else if (state.itemType == 2) {
-    // 回访数据
-    tableData = state.returnItemTableData;
-  } else {
-    tableData = state.otherItemTableData;
-  }
-  // request.post('/platformApi/dataService/diseaseManage/todos', {
-  //   todos: []
-  // })
-  emits("save", tableData);
-  dialogVisible.value = false;
-};
-const onReset = () => {
-  state.checkItemTableData = [];
-  state.otherItemTableData = [];
-  state.returnItemTableData = [];
-  state.itemType = 1;
-  setCheckItemRef.value?.onReset();
-  setOtherItemRef.value?.onReset();
-  setOtherReturnRef.value?.onReset();
-};
-</script>

+ 0 - 148
src/views/healthManagement/components/DiseaseAnalysis.vue

@@ -1,148 +0,0 @@
-<template>
-  <div class="bg-slate-100 p-4 mt-3">
-    <div class="" v-for="(item, index) in tableData" :key="index">
-      <el-text tag="b">{{ item?.title }}</el-text>
-      <div>
-        <div v-if="!item.showType">
-          <div v-for="it in item.content" :key="it">
-            <div v-if="it == '\n'" class="mt-3 mb-3" />
-            <el-text v-else>{{ it }}</el-text>
-            <!-- <el-text>{{ it }}</el-text> -->
-          </div>
-        </div>
-        <div v-else-if="item.showType == 1">
-          <el-tag class="mr-2 mt-2" v-for="it in item.content" :key="it">
-            {{ it }}
-          </el-tag>
-        </div>
-        <div v-else>
-          <div v-for="(it, i) in item.tableResults" :key="i">
-            <div class="mt-2 mb-2">
-              <el-text tag="b">{{ it.classification }}</el-text>
-            </div>
-            <el-table
-              :data="it.formatArray"
-              style="width: 100%"
-              :span-method="objectSpanMethod"
-              border
-            >
-              <el-table-column
-                v-for="(tb, tbIndex) in it.header"
-                :key="tb"
-                :label="tb.name"
-                :prop="`value${tbIndex}`"
-                width="width"
-              >
-                <!-- <template #default="{ row }">{{ row }}</template> -->
-              </el-table-column>
-            </el-table>
-            <div v-if="it?.remark?.length">
-              <div
-                class="bg-white p-4"
-                v-for="remark in it.remark"
-                :key="remark"
-              >
-                <el-text>{{ remark }}</el-text>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-      <el-divider v-if="index != props.list.length - 1" />
-    </div>
-  </div>
-</template>
-<script lang="ts" setup>
-import { onMounted, reactive, defineProps, watch, ref } from "vue";
-import { cloneDeep } from "@pureadmin/utils";
-
-const props = defineProps({
-  list: Array,
-  default: () => {}
-});
-watch(
-  () => props.list,
-  () => {
-    formatArray();
-  },
-  {
-    deep: true
-  }
-);
-const tableData = ref([]);
-
-const formatArray = () => {
-  console.log("监听成功", props.list);
-  const list = cloneDeep(props.list);
-
-  list.forEach(v => {
-    if (v?.showType == 2) {
-      v.tableResults.forEach(vv => {
-        const arr = [];
-        vv.row.map((vRow, rowIndex) => {
-          const obj = {};
-          vRow.map((vvv, iii) => {
-            obj[`value${iii}`] = vvv;
-          });
-          arr.push(obj);
-        });
-        vv["formatArray"] = arr;
-
-        const mergeObj = getSpanArr(arr);
-        vv["formatArray"].forEach(vvv => {
-          vvv["mergeObj"] = mergeObj;
-        });
-      });
-    }
-  });
-  tableData.value = list;
-};
-
-const getSpanArr = data => {
-  const mergeArr = ["value0"];
-  const mergeObj = {};
-  mergeArr.forEach((key, index1) => {
-    let count = 0; // 用来记录需要合并行的起始位置
-    mergeObj[key] = []; // 记录每一列的合并信息
-    data.forEach((item, index) => {
-      // index == 0表示数据为第一行,直接 push 一个 1
-      if (index === 0) {
-        mergeObj[key].push(1);
-      } else {
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
-        if (item[key] === data[index - 1][key]) {
-          mergeObj[key][count] += 1;
-          mergeObj[key].push(0);
-        } else {
-          // 如果当前行和上一行其值不相等
-          count = index; // 记录当前位置
-          mergeObj[key].push(1); // 重新push 一个 1
-        }
-      }
-    });
-  });
-  return mergeObj;
-};
-
-// 默认接受四个值 { 当前行的值, 当前列的值, 行的下标, 列的下标 }
-const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
-  console.log(row);
-
-  const mergeArr = ["value0"];
-  // 判断列的属性
-  if (mergeArr.indexOf(column.property) !== -1) {
-    // 判断其值是不是为0
-    if (row.mergeObj[column.property][rowIndex]) {
-      return [row.mergeObj[column.property][rowIndex], 1];
-    } else {
-      // 如果为0则为需要合并的行
-      return [0, 0];
-    }
-  }
-};
-onMounted(() => {
-  setTimeout(() => {
-    formatArray();
-  }, 500);
-});
-</script>

+ 0 - 338
src/views/healthManagement/components/DiseaseQA.vue

@@ -1,338 +0,0 @@
-<template>
-  <div class="pb-10">
-    <!-- <AutoCompleteStep @confirm="stepConfirm" /> -->
-    <div v-for="(item, index) in list" :key="index" class="mb-6">
-      <div
-        v-for="(child, childIdx) in item.currentData.question"
-        :key="childIdx"
-        class="m-2 my-4 flex item-start"
-      >
-        <div class="w-12 h-12 rounded-full select-none mr-4">
-          <img src="@/assets/icon-ai-avatar.png" alt="" />
-        </div>
-        <div
-          class="drop-shadow p-4 w-fit max-w-[70%] bg-white dialog-content rounded-xl"
-        >
-          <div class="overflow-hidden">
-            <QuestionItem
-              v-model:info="item.currentData.question[childIdx]"
-              class="animate__faster animate__animated animate__slideInRight py-0"
-              :class="{
-                'pointer-events-none filter grayscale':
-                  item.currentData.state < currentState || isEnd
-              }"
-              :style="`transition-delay:${75 * childIdx}ms;`"
-              @checkMatrix="checkMatrix"
-              @reply="reply"
-            ></QuestionItem>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div
-      v-if="!isEnd  && !msgLoading"
-      class="flex justify-start mt-6 px-1"
-    >
-      <el-button type="primary" size="large" class="px-16 ml-16" @click="next"
-        >保存</el-button
-      >
-    </div>
-    <div v-if="msgLoading" class="mb-6">
-      <div class="m-2 flex item-start">
-        <div class="w-12 h-12 rounded-full select-none mr-4">
-          <img src="@/assets/icon-ai-avatar.png" alt="" />
-        </div>
-        <div
-          class="drop-shadow p-4 w-fit max-w-[70%] bg-gray-50 dialog-content rounded-xl"
-        >
-          <div class="overflow-hidden">
-            <span
-              class="px-2 animate__faster animate__animated animate__slideInRight"
-              >分析中...</span
-            >
-          </div>
-        </div>
-      </div>
-    </div>
-    <div v-if="isEnd">
-      <!-- <p>结论:</p> -->
-
-      <div class="m-2 flex item-start">
-        <div class="w-12 h-12 rounded-full select-none mr-4">
-          <img src="@/assets/icon-ai-avatar.png" alt="" />
-        </div>
-        <div
-          class="drop-shadow p-4 w-fit max-w-[70%] bg-gray-50 dialog-content rounded-xl"
-        >
-          <div class="pb-4">
-            <div class="mb-4">
-              <div class="text-gray-700 text-sm mb-2">分析结果:</div>
-              <div>{{ assessmentInfo.result }}</div>
-            </div>
-            <div v-if="assessmentInfo.accordance">
-              <div class="text-gray-700 text-sm mb-2">分析依据:</div>
-              <div
-                v-for="(item, index) in assessmentInfo.accordance"
-                :key="index"
-              >
-                {{ item }}
-              </div>
-            </div>
-          </div>
-          <div class="flex justify-start py-2">
-            <el-button type="warning" plain size="large" @click="reset">
-              重新分析</el-button
-            >
-            <el-button
-              type="primary"
-              plain
-              class="relative bg-white hover:bg-blue-50 hover:text-blue-500"
-              size="large"
-              @click="confirm"
-            >
-              <span class="relative flex h-3 w-3 mr-2">
-                <span
-                  class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"
-                ></span>
-                <span
-                  class="relative inline-flex rounded-full h-3 w-3 bg-blue-600"
-                ></span>
-              </span>
-              <span>查看分析结果</span>
-            </el-button>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { ref } from "vue";
-import {
-  request,
-  parseJSON,
-  formatResultList,
-  formatItemVal,
-  formatData,
-  sleep
-} from "@/utils";
-import QuestionItem from "@/views/dataCenter/components/QuestionItem.vue";
-import AutoCompleteStep from "./AutoCompleteStep.vue";
-import { nextTick } from "vue";
-import { ElMessage } from "element-plus";
-
-const props = defineProps({
-  userId: {
-    type: String,
-    default: ""
-  },
-  diseaseId: {
-    type: String,
-    default: ""
-  }
-});
-const emit = defineEmits(["confirm"]);
-const msgLoading = ref(false);
-const basicData = ref({
-  scenes: "0",
-  userId: props.userId,
-  diseaseId: props.diseaseId,
-  evaluationsNum: 0
-});
-const processData = ref([]);
-const currentState = ref(0);
-const datas = ref();
-const isEnd = ref(false);
-const assessmentInfo = ref();
-const list = ref([]);
-
-const next = () => {
-  const cur = list.value.find(v => v.currentData.state == currentState.value);
-  console.log(cur, cur.currentData.question, currentState.value);
-  if (
-    cur.currentData.question.find(v => {
-      if (v.type == "group") {
-        return v.children.find(v2 =>
-          Array.isArray(v2.value)
-            ? !v2.value.length
-            : !v2.value && v2.value !== 0
-        );
-      } else {
-        return (
-          v.type != "chat" &&
-          (Array.isArray(v.value) ? !v.value.length : !v.value && v.value !== 0)
-        );
-      }
-    })
-  ) {
-    return ElMessage.warning("请作答后保存");
-  }
-  msgLoading.value = true;
-  nextTick(() => {
-    const req = {
-      state: currentState.value,
-      question: cur.currentData.question.map(JSON.stringify),
-      surveys: undefined
-    };
-    const answers = formatData(formatResultList(cur.currentData.question), {
-      type: 2
-    });
-    const surveys = {};
-    answers.forEach(v => {
-      surveys[v.answer.questionNo] = v.answer;
-    });
-    req.surveys = surveys;
-    console.log(req);
-    processData.value.push(req);
-    qa();
-  });
-};
-const qa = async () => {
-  const { data } = await request.post("/algorServer/api/execute/qa", {
-    basicData: basicData.value,
-    processData: processData.value,
-    currentState: currentState.value,
-    datas: datas.value
-  });
-  const { result } = data;
-  if (result) {
-    datas.value = result.datas;
-    if (result.currentData) {
-      result.currentData.question = result.currentData.question
-        ? result.currentData.question?.map(v => parseJSON(v))
-        : [];
-      // result.currentData.question[0].value = ["AwHWXC"];
-      // result.currentData.question[0].value = [0];
-    }
-    if (currentState.value) {
-      await sleep(3e2);
-    }
-    msgLoading.value = false;
-    nextTick(() => {
-      if (!result.isEnd) {
-        if (currentState.value == result.currentData?.state) {
-          list.value.splice(
-            list.value.findIndex(
-              v => currentState.value == v.currentData.state
-            ),
-            1,
-            result
-          );
-        } else {
-          currentState.value = result.currentData?.state;
-          list.value.push(result);
-        }
-      } else {
-        assessmentInfo.value = result.assessmentInfo;
-      }
-      isEnd.value = result.isEnd;
-    });
-  }
-  console.log(data.result);
-};
-
-const reply = item => {
-  formatItemVal(item);
-};
-
-const checkMatrix = (item, rowIdx, colIdx) => {
-  console.log(item);
-
-  let curState = item.matrix[rowIdx][colIdx];
-  let isMultiple = item.isMultiple;
-  let mutuallyExclusive = item.columns[colIdx].mutuallyExclusive;
-  // 单选
-  if (!isMultiple) {
-    item.matrix[rowIdx].forEach((v, k) => {
-      item.matrix[rowIdx][k] = k === colIdx ? !curState : false;
-    });
-  } else {
-    // 多选
-    // 该列有互斥
-    if (mutuallyExclusive) {
-      if (curState) {
-        item.matrix[rowIdx][colIdx] = !curState;
-      } else {
-        item.matrix[rowIdx].forEach((v, k) => {
-          item.matrix[rowIdx][k] = k === colIdx;
-        });
-      }
-    } else {
-      item.matrix[rowIdx].forEach((v, k) => {
-        if (item.columns[k].mutuallyExclusive) {
-          item.matrix[rowIdx][k] = false;
-        }
-      });
-      item.matrix[rowIdx][colIdx] = !item.matrix[rowIdx][colIdx];
-    }
-  }
-  const res = [];
-  item.matrix?.forEach((cols, k1) => {
-    cols &&
-      cols.forEach &&
-      cols?.forEach((c, k2) => {
-        c && res.push(item.rows[k1].label + "" + item.columns[k2].label);
-      });
-  });
-  item.value = res;
-};
-
-const init = async () => {
-  qa();
-};
-init();
-const reset = () => {
-  datas.value = undefined;
-  processData.value = [];
-  currentState.value = 0;
-  isEnd.value = false;
-  list.value = [];
-  qa();
-};
-const confirm = () => {
-  emit("confirm", assessmentInfo.value);
-};
-</script>
-
-<style lang="scss">
-/* 隐藏浏览器默认的滚动条 */
-textarea::-webkit-scrollbar {
-  width: 12px;
-}
-
-/* 轨道 */
-textarea::-webkit-scrollbar-track {
-  background: #f1f1f1;
-}
-
-/* 滑块 */
-textarea::-webkit-scrollbar-thumb {
-  background: #888;
-  border-radius: 20px;
-  cursor: pointer;
-}
-
-/* 滑块悬停状态 */
-textarea::-webkit-scrollbar-thumb:hover {
-  background: #555;
-}
-
-/* 滚动条的角落 */
-textarea::-webkit-scrollbar-corner {
-  background: #f1f1f1;
-}
-.dialog-content {
-  position: relative;
-  &::before {
-    content: "";
-    position: absolute;
-    top: 20px;
-    left: -10px;
-    transform: translateX(-50%);
-    border-width: 10px;
-    border-style: solid;
-    border-color: transparent #fff transparent transparent;
-  }
-}
-</style>

+ 0 - 169
src/views/healthManagement/components/DiseaseVisit.vue

@@ -1,169 +0,0 @@
-vue
-<template>
-  <!-- <div class="bg-[#f0f2f5] sticky z-10 top-0 h-4"></div> -->
-  <div
-    class="bg-white p-4 pb-0 sticky z-10 top-0 flex space-x-2 shadow-sm mr-4"
-  >
-    <!-- <DiseaseVisitData /> -->
-    <el-form :inline="true" class="flex-1">
-      <el-form-item label="" required>
-        <el-select
-          v-model="curDiseaseId"
-          filterable
-          clearable
-          @change="
-            diseaseVisitDateList = diseaseVisitList.find(
-              v => v.diseaseId == curDiseaseId
-            )?.list;
-            sn = '';
-            transferRawJson = undefined;
-          "
-        >
-          <el-option
-            v-for="(item, index) in diseaseVisitList"
-            :key="index"
-            :label="item.diseaseName"
-            :value="item.diseaseId"
-          ></el-option
-        ></el-select>
-      </el-form-item>
-      <el-form-item label="选择回访数据" required>
-        <el-select
-          v-model="sn"
-          :disabled="!curDiseaseId"
-          filterable
-          clearable
-          @change="getDetailBySn"
-          @clear="transferRawJson = undefined"
-        >
-          <el-option
-            v-for="(item, index) in diseaseVisitDateList"
-            :key="index"
-            :label="item.date"
-            :value="item.id"
-          ></el-option>
-        </el-select>
-      </el-form-item>
-    </el-form>
-    <el-form-item v-if="transferRawJson && DiseaseVisitData">
-      <el-button type="primary" @click="save">保存修改</el-button>
-    </el-form-item>
-  </div>
-  <div>
-    <component
-      v-if="transferRawJson && DiseaseVisitData"
-      :is="DiseaseVisitData"
-      ref="diseaseVisitDataRef"
-    >
-      <template v-if="curDiseaseId == 'visitRecord'" #form>
-        <div></div>
-      </template>
-      <template #save>
-        <div></div>
-      </template>
-    </component>
-  </div>
-</template>
-
-<script setup>
-import {
-  ref,
-  reactive,
-  onMounted,
-  watch,
-  provide,
-  defineAsyncComponent,
-  nextTick
-} from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import { useRoute, useRouter } from "vue-router";
-
-import { request, parseJsonData } from "@/utils";
-import dayjs from "dayjs";
-import { QuestionFilled, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-
-const DiseaseVisitData = defineAsyncComponent(() =>
-  import("@/views/dataCenter/components/DiseaseVisitData.vue")
-);
-const [route, router] = [useRoute(), useRouter()];
-const diseaseVisitDataRef = ref();
-const archivesId = ref(route.query.archivesId);
-provide("archivesId", archivesId);
-const transferRawJson = ref();
-provide("transferRawJson", transferRawJson);
-const formId = ref();
-provide("formId", formId);
-const transferRawJsonDiseaseId = ref();
-provide("transferRawJsonDiseaseId", transferRawJsonDiseaseId);
-
-const curDiseaseId = ref();
-const sn = ref();
-provide("sn", sn);
-const diseaseVisitList = ref([]);
-const diseaseVisitDateList = ref([]);
-
-const getDiseaseVisitData = async () => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/diseaseVisit/field/query",
-    {
-      archivesId: route.query.archivesId || route.query.id
-    }
-  );
-  diseaseVisitList.value = data.list;
-  let max = {
-    diseaseId: "",
-    id: "",
-    date: ""
-  };
-  (data.list || []).forEach(v => {
-    (v.list || []).forEach(v2 => {
-      const d = +new Date(v2.date);
-      if (!max.date) {
-        max.date = d;
-        max.diseaseId = v.diseaseId;
-        max.id = v2.id;
-      } else {
-        if (d > max.date) {
-          max.date = d;
-          max.diseaseId = v.diseaseId;
-          max.id = v2.id;
-        }
-      }
-    });
-  });
-  console.log(max);
-  if (max.date) {
-    curDiseaseId.value = max.diseaseId;
-    diseaseVisitDateList.value = diseaseVisitList.value.find(
-      v => v.diseaseId == curDiseaseId.value
-    )?.list;
-    sn.value = max.id;
-    getDetailBySn(max.id);
-  }
-};
-getDiseaseVisitData();
-
-const getDetailBySn = async v => {
-  if (!v) return;
-
-  const { data } = await request.get(`/medicalData/detail`, {
-    params: {
-      sn: sn.value
-    }
-  });
-  transferRawJson.value = undefined;
-  nextTick(() => {
-    const temp = parseJsonData(data.detail.transferRawJson);
-
-    transferRawJson.value = temp?.answers || temp || [];
-    transferRawJsonDiseaseId.value = temp?.diseaseId;
-    formId.value = temp?.formId;
-  });
-};
-const save = async () => {
-  await diseaseVisitDataRef.value?.submitFormData();
-  getDetailBySn(sn.value);
-};
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 17
src/views/healthManagement/components/EvaluateCard.vue

@@ -1,17 +0,0 @@
-<template>
-  <el-card v-bind="$attrs">
-    <template #header>
-      <div>
-        <slot name="header"></slot>
-      </div>
-    </template>
-    <div>
-      <slot></slot>
-    </div>
-    <template #footer>
-      <div>
-        <slot name="footer"></slot>
-      </div>
-    </template>
-  </el-card>
-</template>

+ 0 - 75
src/views/healthManagement/components/FollowUpData.vue

@@ -1,75 +0,0 @@
-<template>
-  <div class="h-full">
-    <el-card shadow="never" class="h-full" v-if="state.options?.length">
-      <template #header>
-        <div>
-          <el-select
-            v-model="state.value"
-            placeholder="请选择随访主题"
-            class="w-full"
-          >
-            <el-option
-              v-for="item in state.options"
-              :key="item.id"
-              :label="`【${item.theme}】 (${item.date})`"
-              :value="item.idx"
-            />
-          </el-select>
-        </div>
-      </template>
-      <el-scrollbar height="calc(77vh)">
-        <div>
-          <div
-            v-if="state.options[state.value]?.content?.viewQuestions?.length"
-          >
-            <div
-              v-for="(item, index) in state.options[state.value].content
-                ?.viewQuestions"
-              :key="index"
-              class="m-1 bg-gray-100 rounded p-4 mb-3"
-            >
-              <SimpleQuestionItem :info="item" :id="item.id" :edit="false" />
-            </div>
-          </div>
-          <div v-else>
-            <el-empty description="暂无随访数据" />
-          </div>
-        </div>
-      </el-scrollbar>
-    </el-card>
-    <el-card v-else shadow="never" class="h-full">
-      <el-empty description="暂无数据" />
-    </el-card>
-  </div>
-</template>
-<script setup>
-import { request } from "@/utils";
-import { reactive, ref } from "vue";
-import SimpleQuestionItem from "@/components/Survey/SimpleQuestionItem.vue";
-import { useRoute } from "vue-router";
-const [route] = [useRoute()];
-
-const archivesId = ref(route.query.archivesId);
-const state = reactive({
-  value: undefined,
-  list: [],
-  options: []
-});
-const getList = () => {
-  request
-    .get(`dataService/schedule/todo/visitList?archiveId=${archivesId.value}`)
-    .then(resp => {
-      console.log("list", resp);
-      state.options = resp.data?.map((item, index) => {
-        return {
-          ...item,
-          idx: index
-        };
-      });
-    });
-};
-const initData = () => {
-  getList();
-};
-initData();
-</script>

+ 0 - 176
src/views/healthManagement/components/HealthManagementPlan.vue

@@ -1,176 +0,0 @@
-<template>
-  <div class="p-4" style="height: 80vh">
-    <el-card shadow="never">
-      <div class="text-center" v-if="!state.list.length">
-        <el-empty />
-        <el-button type="primary" plain class="mb-10" @click="handleAdd"
-          >添加管理计划</el-button
-        >
-      </div>
-      <div v-else>
-        <HealthManagementPlanDetail
-          :list="state?.list"
-          @onChangeStatus="onChangeStatus"
-          @onEdit="onEdit"
-          @onEvaluate="toDetail"
-          @onDelete="onDelete"
-        />
-      </div>
-    </el-card>
-    <ComponentDialogSelectIllness
-      v-model:show="state.visible"
-      nodeTag="功能医学管理"
-      :confirmFn="
-        (diseaseId, name) =>
-          router.push({
-            name: 'healthPlanDetail',
-            query: {
-              archivesId: route.query.archivesId,
-              name,
-              diseaseId
-            }
-          })
-      "
-    />
-    <el-dialog v-model="updateNextTimeVisible" title="修改下次反馈设定">
-      <el-form label-position="top">
-        <el-form-item label="下次评估时间:" required>
-          <el-date-picker
-            v-model="updateNextTime.nextTime"
-            type="date"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            placeholder="请选择评估时间"
-          />
-        </el-form-item>
-        <el-form-item label="下次评估时期望达成效果:" required>
-          <Editor v-model:value="updateNextTime.target" />
-        </el-form-item>
-      </el-form>
-      <el-form-item>
-        <el-button type="primary" @click="saveUpdateNextTime"
-          >保存并提交</el-button
-        >
-      </el-form-item>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import Editor from "@/components/Editor.vue";
-import { request } from "@/utils";
-import { reactive, computed, ref, provide } from "vue";
-
-import { useRouter, useRoute } from "vue-router";
-const [route, router] = [useRoute(), useRouter()];
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-
-import ComponentDialogSelectIllness from "./DialogSelectIllness.vue";
-import HealthManagementPlanDetail from "./HealthManagementPlanDetail.vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-const state = reactive({
-  visible: false,
-  list: []
-});
-
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const getDetail = async () => {
-  const { data } = await request.get(
-    "/platformApi/dataService/healthManage/detail",
-    {
-      params: {
-        archiveId: currentArchiveId.value
-      }
-    }
-  );
-  state.list = data;
-};
-const handleAdd = () => {
-  state.visible = true;
-};
-const updateNextTimeVisible = ref(false);
-const updateNextTime = ref({
-  id: "",
-  nextTime: "",
-  target: ""
-});
-const saveUpdateNextTime = async () => {
-  await request.post(`/dataService/healthManage/update`, updateNextTime.value);
-  ElMessage.success("操作成功");
-  getDetail();
-  updateNextTimeVisible.value = false;
-};
-const onEdit = index => {
-  const current = state.list[index];
-  updateNextTime.value = {
-    id: current.id,
-    nextTime: current.nextTime,
-    target: current.target
-  };
-  updateNextTimeVisible.value = true;
-  // router.push({
-  //   name: "archivesPlanHealth",
-  //   query: {
-  //     archivesId: route.query.archivesId,
-  //     name: state.list[index]?.disease,
-  //     source: state.list[index]?.id,
-  //     diseaseId: state.list[index]?.diseaseId
-  //   }
-  // });
-};
-const toDetail = async index => {
-  // await ElMessageBox.confirm('未到设定的评估时间,是否要忽略设定日期,立即开始评估', '提示')
-  router.push({
-    name: "healthPlanDetail",
-    query: {
-      archivesId: route.query.archivesId,
-      name: state.list[index]?.disease,
-      source: state.list[index]?.source,
-      diseaseId: state.list[index]?.diseaseId
-    }
-  });
-};
-const onDelete = async index => {
-  const { message } = await request.post(
-    "/platformApi/dataService/healthManage/delete",
-    {
-      id: state.list[index]?.id
-    }
-  );
-  ElMessage.success(message);
-  getDetail();
-};
-const onChangeStatus = async row => {
-  const { message } = await request.post(
-    "/platformApi/dataService/healthManage/update/status",
-    {
-      id: row.id,
-      status: row.status ? 0 : 1
-    }
-  );
-  ElMessage.success(message);
-  getDetail();
-};
-getDetail();
-
-const pptNode = ref();
-const getPPTNode = async () => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 1,
-      pagesize: 1,
-      tag: "用户ID",
-      name: route.query.archivesId
-    }
-  });
-  if (data.list[0]) {
-    pptNode.value = data.list[0];
-  }
-};
-getPPTNode();
-provide("pptNode", pptNode);
-</script>

+ 0 - 422
src/views/healthManagement/components/HealthManagementPlanDetail.vue

@@ -1,422 +0,0 @@
-<template>
-  <div>
-    <Auth value="healthManage">
-      <el-button type="primary" @click="handleAddPlan">添加管理计划</el-button>
-    </Auth>
-    <div class="mt-4">
-      <div v-for="(item, index) in props.list" :key="index" class="mb-2">
-        <el-card>
-          <template #header>
-            <div class="flex items-center justify-between">
-              <div class="flex items-center">
-                <h3>管理疾病名称: {{ item.disease }}</h3>
-              </div>
-              <div class="flex items-center">
-                <div v-if="!item.status">
-                  <h4
-                    v-if="
-                      moment().format('YYYY-MM-DD') ==
-                      item?.nextTime?.split(' ')[0]
-                    "
-                    class="text-green-500"
-                  >
-                    今天({{ item.nextTime?.split(" ")[0] }})需要进行评估
-                  </h4>
-                  <h4
-                    v-else-if="
-                      moment().valueOf() >
-                      moment(item?.nextTime?.split(' ')[0].valueOf())
-                    "
-                    class="text-red-500"
-                  >
-                    已超时{{
-                      Number(0 - timeDiffer(item?.nextTime?.split(" ")[0]))
-                    }}天({{ item.nextTime?.split(" ")[0] }} )请尽快评估
-                  </h4>
-                  <h4 v-else>
-                    {{ timeDiffer(item?.nextTime?.split(" ")[0]) }}天后({{
-                      item?.nextTime?.split(" ")[0]
-                    }})将进行下一次评估
-                  </h4>
-                </div>
-                <div v-else>
-                  <h3>管理已暂停</h3>
-                </div>
-                <el-button
-                  class="ml-3"
-                  type="primary"
-                  @click="emits('onEvaluate', index)"
-                  >评估</el-button
-                >
-              </div>
-            </div>
-          </template>
-          <div>
-            <el-row :gutter="10">
-              <el-col :span="12">
-                <template v-if="item.etiologies.length">
-                  <h4>目前主要病因</h4>
-                  <div>
-                    <el-tag
-                      v-for="(tag, tagIdx) in item.etiologies"
-                      :key="tagIdx"
-                      class="m-1"
-                      type="danger"
-                      size="large"
-                      >{{ tag.label }}</el-tag
-                    >
-                  </div>
-                </template>
-                <h4>健康综合评分趋势</h4>
-                <div class="bg-white h-64 rounded shadow">
-                  <Chart ref="chartRef" />
-                </div>
-              </el-col>
-              <el-col :span="12">
-                <h4>
-                  {{ item.createdAt.split(" ")[0] }}
-                  至
-                  {{ item.nextTime?.split(" ")[0] }} 期间(共{{
-                    diffTime(
-                      item.nextTime?.split(" ")[0],
-                      item.createdAt.split(" ")[0]
-                    ) || 1
-                  }}天)管理目标
-                </h4>
-                <div>
-                  <div v-if="!item.status" v-html="item.target" />
-                  <el-empty v-else description="该管理已暂停" />
-                </div>
-              </el-col>
-            </el-row>
-          </div>
-          <template #footer>
-            <div class="flex justify-between">
-              <div>
-                <Auth value="healthManage">
-                  <el-button
-                    type="primary"
-                    link
-                    :icon="Setting"
-                    @click="handleEditItem(index)"
-                    >修改下次评估日期</el-button
-                  >
-                </Auth>
-                <el-button
-                  type="primary"
-                  link
-                  :icon="User"
-                  @click="handleUserPortrait(index)"
-                  >健康画像</el-button
-                >
-                <el-button
-                  type="primary"
-                  link
-                  :icon="Clock"
-                  @click="handleHistory(index)"
-                  >评估历史详情</el-button
-                >
-                <el-button
-                  v-if="pptNode"
-                  type="primary"
-                  link
-                  :icon="VideoPlay"
-                  @click="toPPT"
-                  >讲解</el-button
-                >
-              </div>
-              <div class="flex-right">
-                <Auth value="healthManage">
-                  <el-button
-                    v-if="item.status"
-                    type="primary"
-                    link
-                    :icon="VideoPlay"
-                    style="color: green"
-                    @click="handleChangeStatus(item)"
-                    >恢复管理</el-button
-                  >
-                  <el-button
-                    v-else
-                    type="primary"
-                    link
-                    :icon="VideoPause"
-                    style="color: red"
-                    @click="handleChangeStatus(item)"
-                    >暂停管理</el-button
-                  >
-
-                  <el-popconfirm
-                    title="确定要删除此管理计划吗"
-                    @confirm="emits('onDelete', index)"
-                  >
-                    <template #reference>
-                      <el-button
-                        type="primary"
-                        link
-                        :icon="Delete"
-                        style="color: red"
-                        >删除</el-button
-                      >
-                    </template>
-                  </el-popconfirm>
-                </Auth>
-              </div>
-            </div>
-          </template>
-        </el-card>
-      </div>
-    </div>
-    <ComponentDialogSelectIllness
-      v-model:show="state.visibleAdd"
-      nodeTag="功能医学管理"
-      :confirmFn="
-        (diseaseId, name) =>
-          router.push({
-            name: 'healthPlanDetail',
-            query: {
-              archivesId: route.query.archivesId,
-              name,
-              diseaseId
-            }
-          })
-      "
-    />
-    <el-dialog title="健康画像" v-model="userPortraitVisible" width="85%">
-      <div v-if="userPortraitVisible">
-        <component :is="HealthPortrait" />
-      </div>
-    </el-dialog>
-    <el-dialog title="评估历史详情" v-model="state.visibleHistory" width="85%">
-      <div>
-        <DialogHealthManageEvaluationHistory
-          :list="transformDataExpand([state.currentItem], 'histories')"
-          ref="historyRef"
-        />
-      </div>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import {
-  ref,
-  reactive,
-  defineProps,
-  defineEmits,
-  defineAsyncComponent,
-  provide,
-  inject
-} from "vue";
-import * as echarts from "echarts";
-import { nextTick } from "process";
-import moment from "moment";
-// import dayjs from "dayjs";
-import { useRoute, useRouter } from "vue-router";
-import ComponentDialogSelectIllness from "./DialogSelectIllness.vue";
-import DialogHealthManageEvaluationHistory from "./DialogHealthManageEvaluationHistory.vue";
-import Chart from "@/components/Chart.vue";
-
-import { ElMessage, ElMessageBox } from "element-plus";
-
-import {
-  Setting,
-  Clock,
-  User,
-  VideoPause,
-  VideoPlay,
-  Delete
-} from "@element-plus/icons-vue";
-import { request, transformDataExpand, timeDiffer } from "@/utils";
-
-const pptNode = inject("pptNode");
-const [route, router] = [useRoute(), useRouter()];
-const props = defineProps({
-  list: Array,
-  default: () => []
-});
-const emits = defineEmits("onChangeStatus", "onEdit", "onEvaluate", "onDelete");
-const state = reactive({
-  visibleAdd: false,
-  visibleBacklog: false,
-  visibleHistory: false,
-  currentItem: {}
-});
-const chartRef = ref();
-const historyRef = ref();
-const initChart = index => {
-  props.list.map((item, i) => {
-    const list = transformDataExpand([item], "histories");
-    chartRef.value[i].setOption({
-      title: {
-        text: "",
-        top: "10",
-        left: "10"
-      },
-      grid: {
-        left: "5%",
-        right: "5%",
-        bottom: "15%"
-      },
-      xAxis: {
-        type: "category",
-        data: list.map(v => v.createdAt).reverse(),
-        axisTick: { show: false },
-        axisLabel: {
-          formatter: params => {
-            return params?.split(" ")[0];
-          }
-        }
-      },
-      yAxis: {
-        type: "value",
-        axisLine: { show: false },
-        axisTick: { show: false },
-        axisLabel: { show: false }
-      },
-      series: [
-        {
-          data: list.map(v => Number(v.score)).reverse(),
-          type: "line",
-          itemStyle: {
-            normal: {
-              // 这里就可以实现,配置柱状图的颜色
-              color: function (params) {
-                const colorList = [
-                  "#ccc",
-                  "#c101c1",
-                  "#FCCE10",
-                  "#E87C25",
-                  "#27727B",
-                  "#D7504B"
-                ];
-                return colorList[params.value];
-              }
-            }
-          },
-          label: {
-            show: true,
-            position: "top",
-            formatter: params => {
-              return `${params.value}分`;
-            }
-          },
-          smooth: true
-        }
-      ]
-    });
-  });
-};
-const diffTime = (end, start) => {
-  return moment(end).diff(moment(start), "day");
-};
-const handleAddPlan = () => {
-  state.visibleAdd = true;
-};
-const handleBacklog = () => {
-  state.visibleBacklog = true;
-};
-
-const HealthPortrait = defineAsyncComponent(() =>
-  import("../healthPlan/HealthPortrait.vue")
-);
-const userHealthPortraitState = ref();
-const userPortraitVisible = ref(false);
-const handleUserPortrait = index => {
-  const current = props.list[index];
-  console.log(current);
-  userHealthPortraitState.value = { ...current };
-  userHealthPortraitState.value.etiologies =
-    userHealthPortraitState.value.etiologies.map(v => {
-      return typeof v == "string" ? { label: v } : v;
-    });
-  initDisease(current.diseaseId);
-  userPortraitVisible.value = true;
-};
-provide("parentState", userHealthPortraitState);
-const diseaseMangeNode = ref();
-const initDisease = async diseaseId => {
-  const nodes = await getNodeRelationship(diseaseId, "功能医学管理");
-  diseaseMangeNode.value = nodes[0].mId;
-};
-provide("diseaseMangeNode", diseaseMangeNode);
-const getNodes = async query => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 9999,
-      pagesize: 9999,
-      ...query
-    }
-  });
-  return data;
-};
-provide("getNodes", getNodes);
-const getNodeRelationship = async (id, tag, reverse = undefined) => {
-  const { data } = await request.get(`/graphService/open/node/relationship`, {
-    params: {
-      id,
-      rName: tag,
-      reverse
-    }
-  });
-  return data;
-};
-provide("getNodeRelationship", getNodeRelationship);
-const getBatchNodeRelationships = async (ids, tag, reverse = undefined) => {
-  const { data } = await request.get(`/graphService/open/node/relationships`, {
-    params: {
-      ids,
-      rName: tag,
-      reverse
-    }
-  });
-  return data;
-};
-provide("getBatchNodeRelationships", getBatchNodeRelationships);
-const handleHistory = index => {
-  state.currentItem = props.list[index];
-  state.visibleHistory = true;
-  console.log(historyRef.value, state.currentItem);
-
-  historyRef.value?.initChart();
-};
-const handleChangeStatus = row => {
-  ElMessageBox.confirm(
-    row.status
-      ? "确定继续次疾病的管理?"
-      : "确定要暂停这个管理吗?暂停后不可再进行评估",
-    "",
-    {
-      distinguishCancelAndClose: true,
-      confirmButtonText: "确定",
-      cancelButtonText: "取消"
-    }
-  )
-    .then(async () => {
-      emits("onChangeStatus", row);
-    })
-    .catch(err => {});
-};
-const handleEditItem = index => {
-  emits("onEdit", index);
-};
-
-nextTick(initChart);
-
-const toPPT = () => {
-  const url = `${location.origin}${location.pathname}#/healthManagement/ppt?archivesId=${route.query.archivesId}`;
-  console.log(url);
-  const newWindow = window.open(url);
-  if (newWindow) {
-    newWindow.addEventListener("load", () => {
-      newWindow.postMessage("goFullscreen", "*");
-    });
-  }
-};
-</script>
-<style scoped lang="scss">
-.left-chart {
-  width: 500px;
-  height: 400px;
-}
-</style>

+ 0 - 438
src/views/healthManagement/components/HorizontalContrast.vue

@@ -1,438 +0,0 @@
-<template>
-  <div
-    v-if="!props.hideCtrl"
-    class="flex items-center justify-end p-4 space-x-4"
-  >
-    <el-button type="warning" plain @click="clearCompareReport"
-      >清空并保存</el-button
-    >
-    <div class="flex-1 flex items-center justify-end">
-      <el-button type="success" plain @click="getData">更新对比数据</el-button>
-      <el-button type="primary" @click="saveCompareReport">保存</el-button>
-    </div>
-  </div>
-  <div class="p-4 w-full overflow-x-auto">
-    <slot name="title1">
-      <p class="font-bold text-lg mb-2">疾病风险评估对比及趋势</p>
-    </slot>
-    <!-- {{state}} -->
-    <!-- <table class=" border-collapse bg-white w-full mb-4">
-
-      <tr
-          class="">
-        <td class="border border-gray-200 px-2 h-[64px] whitespace-nowrap">
-          <div>
-            <span>疾病</span>
-            <span>时间</span>
-          </div>
-        </td>
-        <td
-          v-for="(col, colIdx) in state.tableHeaderColumns" :key="colIdx"
-          class="border border-gray-200 px-2 h-[64px] whitespace-nowrap">{{ col }}</td>
-
-        <td class="border border-gray-200 px-2 h-[64px] whitespace-nowrap">趋势</td>
-      </tr>
-      <tr v-for="(item, index) in state.diseaseList" :key="index">
-        <td class="border border-gray-200 p-2">{{ item.name }}</td>
-        <td
-          v-for="(col, colIdx) in state.tableHeaderColumns" :key="colIdx"
-          class="border border-gray-200 text-sm text-center  p-2"
-        >
-          <span
-            :class="['text-gray-500', 'text-green-500', 'text-yellow-500', 'text-red-600', 'text-red-500'][item.list[colIdx]?.riskDegree]"
-          >{{ item.list[colIdx]?.riskDesc || '缺乏数据' }}</span>
-        </td>
-        <td class="border border-gray-200">
-          <div class="w-40">
-            <div :ref="r => chartRefs[index] = r" class="h-24 w-auto"></div>
-          </div>
-        </td>
-      </tr>
-    </table> -->
-    <div v-for="(item, index) in diseaseList" :key="index" class="mb-4">
-      <SubTitle :type="degreeLabel[item.list.at(-1).riskDegree]?.label">
-        <span>{{ item.name }}</span>
-      </SubTitle>
-      <table class="border-collapse bg-white w-full table-fixed">
-        <tr class="page-break-inside-avoid bg-gray-200">
-          <td
-            :colspan="state.tableHeaderColumns?.length + 1"
-            class="font-bold border-x border-gray-200 p-2 text-gray-700 bg-gray-50 whitespace-nowrap"
-          >
-            疾病风险趋势对比
-          </td>
-        </tr>
-        <tr class="page-break-inside-avoid">
-          <td
-            class="border border-gray-200 p-2 text-gray-700 whitespace-nowrap"
-          >
-            <div>
-              <span>风险趋势</span>
-              <!-- <span>时间</span> -->
-            </div>
-          </td>
-          <td
-            v-for="(col, colIdx) in state.tableHeaderColumns"
-            :key="colIdx"
-            class="border border-gray-200 p-2 text-gray-700 whitespace-nowrap"
-          >
-            {{ col }}
-          </td>
-        </tr>
-        <tr class="page-break-inside-avoid">
-          <td class="border border-gray-200 p-2" :class="item.riskTip?.class">
-            {{ item.riskTip?.label }}
-          </td>
-          <td
-            v-for="(col, colIdx) in state.tableHeaderColumns"
-            :key="colIdx"
-            class="border border-gray-200 text-sm text-left p-2"
-          >
-            <span
-              :class="
-                [
-                  'text-gray-500',
-                  'text-green-500',
-                  'text-yellow-500',
-                  'text-red-600',
-                  'text-violet-700'
-                ][item.list[colIdx]?.riskDegree]
-              "
-              >{{ item.list[colIdx]?.riskDesc || "缺乏数据" }}</span
-            >
-          </td>
-        </tr>
-        <div
-          v-if="!diseaseList.length"
-          class="break-inside-avoid page-break-auto flex flex-col items-center justify-center py-6 mb-4 border border-solid border-gray-200 rounded-b"
-        >
-          <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-          <div class="text-gray-500 text-xs text-center mt-4">暂无数据</div>
-        </div>
-      </table>
-      <table
-        v-if="item.medList?.length"
-        class="border-collapse bg-white w-full table-fixed"
-      >
-        <tr class="page-break-inside-avoid bg-gray-200">
-          <td
-            :colspan="state.tableHeaderColumns?.length + 1"
-            class="font-bold border-x border-gray-200 p-2 text-gray-700 bg-gray-50 whitespace-nowrap"
-          >
-            主要异常结果对比
-          </td>
-        </tr>
-        <tr class="page-break-inside-avoid">
-          <td
-            class="border border-gray-200 p-2 text-gray-700 whitespace-nowrap"
-          >
-            <div>
-              <span>项目</span>
-            </div>
-          </td>
-          <td
-            v-for="(col, colIdx) in state.tableHeaderColumns"
-            :key="colIdx"
-            class="border border-gray-200 p-2 text-gray-700 whitespace-nowrap"
-          >
-            {{ col }}
-          </td>
-        </tr>
-        <tr
-          v-for="(child, childIdx) in item.medList"
-          :key="childIdx"
-          class="page-break-inside-avoid"
-        >
-          <td class="border border-gray-200 p-2">{{ child.name }}</td>
-          <td
-            v-for="(col, colIdx) in state.tableHeaderColumns"
-            :key="colIdx"
-            class="border border-gray-200 text-sm text-left p-2"
-          >
-            <div v-for="(med, medIdx) in child.list[colIdx]" :key="medIdx">
-              <span class="text-sm">{{
-                med?.value === 0 || med?.value ? med?.value : "-"
-              }}</span>
-              <span
-                v-if="med?.value || med?.value === 0"
-                class="text-xs text-gray-500"
-                >{{ med?.unit }}</span
-              >
-            </div>
-            <span v-if="!child.list[colIdx]?.length">-</span>
-          </td>
-        </tr>
-      </table>
-    </div>
-
-    <!-- <el-table :data="state.diseaseList" table-layout="auto">
-      <el-table-column label="疾病" prop="name" fixed="left"></el-table-column>
-      <el-table-column :label="col" v-for="(col, colIdx) in state.tableHeaderColumns" :key="colIdx">
-        <template #header>
-          <span class="whitespace-nowrap">{{col}}</span>
-        </template>
-        <template #default="{ row, $index }">
-          <span
-            :class="['text-gray-500', 'text-green-500', 'text-yellow-500', 'text-red-600', 'text-red-700'][row.list[colIdx]?.riskDegree]"
-          >{{ row.list[colIdx]?.riskDesc || '缺乏分析数据' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="趋势" width="200px">
-        <template #default="{row, $index}">
-          <div class="w-40">
-            <div :ref="r => chartRefs[$index] = r" class="h-24 w-[160px]"></div>
-          </div>
-        </template>
-      </el-table-column>
-    </el-table> -->
-    <!-- <slot name="title2">
-      <p class="font-bold text-lg mb-2 mt-6">异常项目横向对比</p>
-    </slot>
-    <div v-for="(item, index) in state.medDataList" :key="index" class="rounded mb-4 last:mb-0">
-
-        <div
-          class=" py-2 px-4 flex items-center justify-between bg-[#f9fafb] border border-b-0 border-solid border-gray-200"
-        >
-          <span>{{ item.name }}</span>
-        </div>
-        <div class="w-full overflow-x-auto">
-          <div class="flex flex-wrap">
-            <div
-              v-for="(col, colIdx) in item.list"
-              :key="colIdx"
-              class="flex-1 border-t border-b border-l last:border-r border-solid border-gray-200"
-            >
-              <div
-                class="p-2 text-sm border-solid border-b border-gray-200"
-              >
-                {{ col.date }}
-              </div>
-              <div>
-                <div class="p-2 text-sm">
-                  <div>
-                    <span class="align-middle"
-                      >{{ col.value
-                      }}{{ col.unit && col.unit != "-" ? col.unit : "" }}
-                    </span>
-                    <template v-if="col.reference">
-                      <el-tooltip>
-                        <QuestionFilled
-                          class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                        />
-                        <template #content>
-                          <div class="text-sm">
-                            参考范围:{{ col.reference }}
-                          </div>
-                        </template>
-                      </el-tooltip>
-                    </template>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-
-        </div>
-      </div> -->
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  shallowRef,
-  watch,
-  ref,
-  nextTick,
-  reactive,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent
-} from "vue";
-import { request } from "@/utils";
-import { ElMessage, ElMessageBox } from "element-plus";
-// import echarts from "@/plugins/echarts";
-import PageTitle from "@/components/PageTitle.vue";
-import SubTitle from "@/components/SubTitle.vue";
-import SectionText from "@/components/SectionText.vue";
-import { useRoute, useRouter } from "vue-router";
-const [route, router] = [useRoute(), useRouter()];
-const props = defineProps({
-  data: {
-    type: Array,
-    default: undefined
-  },
-  archivesId: {
-    type: String,
-    default: undefined
-  },
-  hideCtrl: false
-});
-const degreeLabel = {
-  4: { label: "diagnosis", thClass: "text-violet-800 bg-violet-200" },
-  3: { label: "danger", thClass: "text-red-500 bg-red-50" },
-  2: { label: "warning", thClass: "text-yellow-600 bg-yellow-100" },
-  0: { label: "success", thClass: "text-green-800 bg-green-200" },
-  1: { label: "primary", thClass: "text-blue-800 bg-blue-200" }
-};
-// const chartRefs = ref([])
-// const renderChart = (el, data) => {
-//   // 基于准备好的dom,初始化echarts实例
-//   const myChart = echarts.init(el);
-//   const riskDegree2Val = {
-//     0: 0,
-//     1: 0,
-//     2: 1,
-//     3: 2,
-//     4: 3,
-//   }
-//   let values = data.list.map(v => v.riskDegree)
-
-//   values = values.map((v, i) => {
-//     if (!v) {
-//       v = values[i - 1] || 0
-//     }
-//     return riskDegree2Val[v] ? (riskDegree2Val[v] || 3) : riskDegree2Val[v]
-//   })
-//   const option = {
-//     grid: {
-//       left: "5%",
-//       right: "5%",
-//       top: "8%",
-//       bottom: "0%",
-//       containLabel: true
-//     },
-//     xAxis: {
-//       show: false,
-//       type: "category",
-//       boundaryGap: false,
-//     },
-//     yAxis: {
-//       show: false,
-//       type: "value",
-//       max: 4
-//     },
-//     series: [
-//       {
-//         name: "trend",
-//         type: "line",
-//         areaStyle: {
-//           color: {
-//             type: "linear",
-//             x: 0,
-//             x2: 0,
-//             y: 0,
-//             y2: 1,
-//             colorStops: [
-//               { offset: 0, color: "rgba(0, 55, 255, 0.9)" }, // 深色靠近数据点
-//               { offset: .6, color: "rgba(0, 55, 255, 0.3)" }, // 深色靠近数据点
-//               { offset: 1, color: "rgba(0, 0, 255, 0.0)" } // 透明靠近X轴
-//             ]
-//           }
-//         },
-//         // symbolSize: 4,
-//         data: values
-//       }
-//     ]
-//   };
-//   // 绘制图表
-//   myChart.setOption(option);
-// };
-const state = ref({
-  diseaseList: [],
-  medDataList: [],
-  tableHeaderColumns: []
-});
-const compareReportData = inject("compareReportData");
-const getData = async () => {
-  let temp;
-  if (compareReportData?.value) {
-    temp = compareReportData.value;
-  } else {
-    const { data } = await request.get(
-      `/idcService/mechanism/medicalData/compareReport/detail`,
-      {
-        params: {
-          sn: route.query.sn,
-          archivesId: props.archivesId
-        }
-      }
-    );
-    temp = data.detail?.data;
-  }
-  state.value = {
-    ...state.value,
-    ...(temp.compareDataForYear || {}),
-    medDataList: temp.compareData.medDatas
-  };
-  // nextTick(() => {
-  //   temp && nextTick(() => {
-  //     chartRefs.value.length && chartRefs.value.forEach((chartRef, index) => {
-  //       renderChart(chartRef, state.value.diseaseList[index])
-  //     })
-  //   })
-  // })
-  // saveCompareReport()
-};
-const clearCompareReport = async () => {
-  const { data } = await request.post(
-    `/idcService/mechanism/medicalData/compareReport/delete`,
-    {
-      archivesId: props.archivesId
-    }
-  );
-  // getData()
-  ElMessage.success("操作成功");
-};
-const saveCompareReport = async () => {
-  const { data } = await request.post(
-    `/idcService/mechanism/medicalData/compareReport/save`,
-    {
-      archivesId: props.archivesId,
-      data: state.value
-    }
-  );
-  ElMessage.success("操作成功");
-};
-
-const diseaseList = computed(() =>
-  (state.value?.diseaseList || [])
-    .map(v => {
-      let riskTip = "";
-
-      if (v.list.length > 1) {
-        const last = v.list.at(-1).riskDegree;
-        const prev = v.list.at(-2).riskDegree;
-        if (last == 4) {
-          riskTip = { label: "已确诊", class: "text-violet-800" };
-        } else if (last > prev && last > 1) {
-          riskTip = { label: "风险在增加↑", class: "text-red-500" };
-        } else if (last > prev && last == 1) {
-          riskTip = { label: "暂无风险", class: "text-green-500" };
-        } else if (last < prev && last > 0) {
-          riskTip = { label: "风险在降低↓", class: "text-green-500" };
-        } else if (last < prev && last == 0) {
-          riskTip = { label: "风险变化情况未知 -", class: "text-yellow-500" };
-        } else if (last == prev && last && prev) {
-          riskTip = { label: "风险暂无变化 -", class: "text-yellow-500" };
-        } else if (last == prev && !last && !prev) {
-          riskTip = { label: "风险变化情况未知 -", class: "text-yellow-500" };
-        } else {
-          riskTip = { label: "风险暂无变化 -", class: "text-yellow-500" };
-        }
-      }
-      return {
-        ...v,
-        riskTip,
-        list: v.list
-      };
-    })
-    .sort((a, b) => b.list.at(-1).riskDegree - a.list.at(-1).riskDegree)
-);
-onMounted(() => {
-  getData();
-});
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 300
src/views/healthManagement/components/IndicatorTrends.vue

@@ -1,300 +0,0 @@
-<template>
-  <!-- <div class="bg-[#f0f2f5] sticky z-10 top-0 h-4"></div> -->
-  <div
-    class="bg-white p-4 sticky z-10 top-4 flex items-center flex-wrap space-x-2 mr-4 border border-gray-100 rounded"
-  >
-    <span class="text-sm text-gray-600">关键检查查询:</span>
-    <el-select
-      v-model="filter.nodes"
-      class="mb-2"
-      multiple
-      filterable
-      clearable
-      collapse-tags
-    >
-      <el-option
-        v-for="(item, index) in nodes"
-        :key="index"
-        :label="item.name"
-        :value="item.id"
-      ></el-option>
-    </el-select>
-    <div class="mb-2">
-      <el-date-picker
-        v-model="filterDate"
-        type="daterange"
-        format="YYYY/MM/DD"
-        value-format="YYYY-MM-DD"
-        start-placeholder="请选择"
-        end-placeholder="请选择"
-      />
-    </div>
-
-    <el-button type="primary" class="mb-2" @click="search">搜索</el-button>
-    <el-button type="warning" class="mb-2" plain @click="reset">重置</el-button>
-  </div>
-  <div class="mt-6 mr-4">
-    <div
-      v-for="(item, index) in list"
-      :key="index"
-      class="bg-white p-4 mb-4 border shadow-sm border-gray-100 rounded"
-    >
-      <!-- <div>
-        <span>{{ item.name }}</span>
-      </div> -->
-      <div v-if="item.isBodyMatter" class="h-64">
-        <Chart
-          :ref="
-            r => {
-              chartRefs[index] = r;
-            }
-          "
-        />
-      </div>
-      <div v-else class="w-full overflow-x-auto">
-        <table class="min-w-full bg-white text-gray-700 table-fixed">
-          <tr class="font-bold">
-            <td class="border border-solid border-gray-100 p-2"></td>
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-              v-for="(col, index) in item.list"
-              :key="index"
-            >
-              {{ dayjs(col.date * 1000).format("YYYY-MM-DD") }}
-            </td>
-          </tr>
-          <tr>
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-            >
-              {{ item.name }}
-            </td>
-            <td
-              v-for="(col, colIdx) in item.list"
-              :key="colIdx"
-              class="border border-solid border-gray-100"
-            >
-              <div class="p-2 text-sm">
-                <span class="align-middle"
-                  >{{ col.value }}
-                  {{ col.unit && col.unit != "-" ? col.unit : "" }}
-                </span>
-                <template v-if="col.reference">
-                  <el-tooltip>
-                    <QuestionFilled
-                      class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                    />
-                    <template #content>
-                      <div class="text-sm">参考范围:{{ col.reference }}</div>
-                    </template>
-                  </el-tooltip>
-                </template>
-              </div>
-            </td>
-          </tr>
-        </table>
-      </div>
-    </div>
-    <el-empty v-if="!list.length"></el-empty>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  ref,
-  reactive,
-  inject,
-  nextTick,
-  onMounted,
-  defineAsyncComponent
-} from "vue";
-import dayjs from "dayjs";
-import { useRoute, useRouter } from "vue-router";
-import { QuestionFilled, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-
-import { request, formateArchivesModuleValue, deepClone } from "@/utils";
-import Chart from "@/components/Chart.vue";
-
-const route = useRoute();
-const router = useRouter();
-
-const props = defineProps({
-  nodeId: {
-    type: String,
-    default: ""
-  }
-});
-
-const filter = ref({
-  nodes: []
-});
-const defaultNodes = ref([]);
-const filterDate = ref([]);
-
-const nodes = ref([]);
-const searchNodes = async () => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/primaryIndicatorCharts/query",
-    {
-      archivesId: route.query.archivesId,
-      nodeIds: [],
-      dates: [],
-      needCharts: false
-    }
-  );
-  nodes.value = data.list;
-  // filter.value.nodes = data.list.map(v => v.id);
-  // filter.value.nodes = [
-  //   "4:aad18a76-6ee3-48a0-bec9-4f7e0bb822dc:357",
-  //   ...data.list.map(v => v.id)
-  // ];
-};
-const list = ref([]);
-const search = async () => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/primaryIndicatorCharts/query",
-    {
-      archivesId: route.query.archivesId,
-      nodeIds: filter.value.nodes,
-      dates: filterDate.value || [],
-      needCharts: true
-    }
-  );
-  list.value = data.list;
-  chartRefs.value = Array(data.list.length).fill(null);
-  nextTick(() => {
-    list.value.forEach((v, i) => {
-      v.isBodyMatter && setOption(chartRefs.value[i], v);
-    });
-  });
-};
-
-const init = async () => {
-  await searchNodes()
-  await searchRelateNodes(props.nodeId);
-  search();
-};
-const chartRefs = ref([]);
-const setOption = (cRef, item) => {
-  console.log(cRef, item);
-  const opt = {
-    title: {
-      text: item.name,
-      top: "10",
-      left: "10"
-    },
-    grid: {
-      left: "5%",
-      right: "5%",
-      bottom: "20%"
-    },
-    legend: {
-      top: "bottom"
-    },
-    xAxis: {
-      type: "category",
-      data: []
-    },
-    tooltip: {
-      formatter(param) {
-        return `${param.seriesName}: ${param.value}${param.data?.unit}`;
-      }
-    },
-    yAxis: {
-      type: "value",
-      axisLine: { show: false },
-      axisTick: { show: false }
-      // axisLabel: { show: false }
-    },
-    series: []
-  };
-  if (item.name == "血压") {
-    const arr1 = [];
-    const arr2 = [];
-    item.list.forEach(v => {
-      const val = v.value.split("/");
-      arr1.push({
-        ...v,
-        value: val[0]
-      });
-      arr2.push({
-        ...v,
-        value: val[1]
-      });
-    });
-
-    opt.series = [
-      {
-        name: "收缩压",
-        data: arr1,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      },
-      {
-        name: "舒张压",
-        data: arr2,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      }
-    ];
-  } else {
-    opt.series = [
-      {
-        name: item.name,
-        data: item.list,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      }
-    ];
-  }
-  opt.series.forEach(v => {
-    v.data = v.data.map(d => {
-      const val = /(\d+(\.\d+)?)/.exec(String(d.value));
-      if (val) {
-        d.value = val[0] || d.value;
-      }
-      if (isNaN(Number(d.value))) {
-        d.value = null
-      }
-      return d
-    }).filter(d => d.value != null);
-  });
-  opt.xAxis.data = opt.series[0].data.map(d => dayjs(d.date * 1000).format("YYYY-MM-DD"))
-  console.log(opt);
-
-  cRef && cRef.setOption(opt);
-};
-onMounted(() => {
-  init();
-});
-
-const searchRelateNodes = async id => {
-  console.log(id);
-  if (!id) return;
-  const { data } = await request.get(`/graphService/open/node/related`, {
-    params: {
-      id,
-      relationship: "关键指标"
-    }
-  });
-  defaultNodes.value = (data || []).map(v => v.id).filter(v => nodes.value.find(v2 => v2.id == v));
-  filter.value.nodes = defaultNodes.value;
-};
-const reset = () => {
-  filter.value.nodes = defaultNodes.value;
-  search();
-};
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 73
src/views/healthManagement/components/LastTimeContent.vue

@@ -1,73 +0,0 @@
-<template>
-  <div class="space-y-4 p-4 pl-0">
-    <div class="bg-white shadow mb-4">
-      <div class="border-0 border-b border-solid border-gray-100 p-2">
-        设置的评估时间
-      </div>
-      <div class="p-4"></div>
-    </div>
-    <div class="bg-white shadow mb-4">
-      <div class="border-0 border-b border-solid border-gray-100 p-2">
-        上次评估主要存在的问题
-      </div>
-      <div class="p-4">
-        <el-tag>血脂异常</el-tag>
-      </div>
-    </div>
-    <div class="bg-white shadow mb-4">
-      <div class="border-0 border-b border-solid border-gray-100 p-2">
-        <span>设置的管理目标</span>
-      </div>
-      <div class="p-4"></div>
-    </div>
-    <div class="bg-white shadow mb-4">
-      <div class="border-0 border-b border-solid border-gray-100 p-2">
-        <span>设置的该用户待办事项完成情况</span>
-      </div>
-      <div class="p-4">
-        <div class="space-y-2 text-sm">
-          <div
-            v-for="(item, index) in 9"
-            :key="index"
-            :class="{
-              'line-through text-gray-500': !(index % 3)
-            }"
-          >
-            2024-3-1 进行1次如下事项:洗脚城按摩 备注:688套餐
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="bg-white shadow mb-4">
-      <div class="border-0 border-b border-solid border-gray-100 p-2">
-        <span>设置的该用户的个性化健康建议</span>
-      </div>
-      <div class="p-4"></div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  ref,
-  reactive,
-  inject,
-  onActivated,
-  onMounted,
-  defineAsyncComponent
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { request, formateArchivesModuleValue, deepClone } from "@/utils";
-import Chart from "@/components/Chart.vue";
-
-const route = useRoute();
-const router = useRouter();
-const init = async () => {};
-onMounted(() => {
-  init();
-});
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 505
src/views/healthManagement/components/LatestUserDataAnalysis.vue

@@ -1,505 +0,0 @@
-<template>
-  <div class="bg-white p-4">
-    <el-descriptions
-      v-if="resultRawJson?.result"
-      title="用户信息"
-      :column="2"
-      border
-      class="mb-8"
-    >
-      <el-descriptions-item label="姓名">{{
-        resultRawJson.result.userInfo.name
-      }}</el-descriptions-item>
-      <el-descriptions-item label="性别">{{
-        resultRawJson.result.userInfo.gender
-      }}</el-descriptions-item>
-      <el-descriptions-item label="体检年龄">{{
-        resultRawJson.result.userInfo.examAge
-      }}</el-descriptions-item>
-      <el-descriptions-item label="体检日期">
-        <!-- {{resultRawJson.result.assessmentDate}} -->
-        {{ dayjs(resultRawJson.result.examDate * 1000).format("YYYY-MM-DD") }}
-      </el-descriptions-item>
-    </el-descriptions>
-    <page-title>
-      <template #icon>
-        <!-- <img
-          src="@/assets/riskAnalysis/icon-overflow.png"
-          alt=""
-          class="h-full"
-        /> -->
-      </template>
-      <span>{{ "健康状况概览" }}</span>
-    </page-title>
-    <div class="px-4 py-8 mb-8">
-      <!-- 标题 -->
-      <!-- <h2 class="text-xl font-bold mb-4 text-center">健康风险评估</h2> -->
-
-      <!-- 图表容器,使用背景渐变和 Grid 布局 -->
-      <div class="relative w-full p-4 chart-background">
-        <!-- Y轴线条 -->
-        <div class="absolute -left-4 top-4 h-full flex items-center">
-          <!-- Y轴线条 -->
-          <div class="w-[1px] bg-gray-400 h-full"></div>
-          <!-- Y轴箭头头部 -->
-          <div class="arrow-y-head"></div>
-        </div>
-
-        <!-- X轴线条 -->
-        <div
-          class="absolute -bottom-4 -left-4 w-full flex items-center justify-end"
-        >
-          <!-- X轴线条 -->
-          <div class="h-[1px] bg-gray-400 w-full"></div>
-          <!-- X轴箭头头部 -->
-          <div class="arrow-x-head"></div>
-        </div>
-        <!-- Y轴注释 -->
-        <div
-          class="flex flex-col absolute top-1/2 -left-4 transform -translate-x-1/2 -translate-y-1/2 text-sm text-gray-600"
-        >
-          <div class="bg-white py-2">
-            <div
-              class="flex flex-col items-center justify-center gap-1"
-              v-html="
-                '健康威胁程度'
-                  .split('')
-                  .map(s => `<span>${s}</span>`)
-                  .join('')
-              "
-            ></div>
-          </div>
-        </div>
-
-        <!-- X轴注释 -->
-        <div
-          class="absolute z-10 bottom-0 left-1/2 transform -translate-x-1/2 translate-y-6 text-center text-gray-600 text-sm"
-        >
-          <div class="flex-1 bg-white px-2">健康干预优先级</div>
-        </div>
-        <!-- 分区布局,根据风险等级和干预优先度沿对角线排列 -->
-        <table class="w-full min-h-[400px] table-fixed">
-          <tr v-for="(row, rowIdx) in zones" :key="rowIdx">
-            <td v-for="(col, colIdx) in row" :key="colIdx">
-              <div
-                v-for="(condition, cIndex) in col.conditions"
-                :key="cIndex"
-                class="inline-flex items-center text-xs px-2 py-1 m-1"
-              >
-                <span
-                  class="inline-block align-middle rounded-full bg-blue-700 p-1 border-2 border-solid border-blue-200 mr-1"
-                ></span>
-                <span class="align-middle whitespace-pre-wrap break-all">{{
-                  condition.name
-                }}</span>
-              </div>
-              <div v-if="!col.conditions?.length" class="h-10"></div>
-            </td>
-          </tr>
-        </table>
-      </div>
-    </div>
-    <div v-if="compareSuggestion && compareSuggestion != '<p><br></p>'" class="mb-8">
-      <sub-title :custom-bg="['#3824ed', 'rgba(56, 36, 237, .1)']">
-        <span>健康建议要点</span>
-      </sub-title>
-      <div
-        class="bg-gray-50 rounded-b p-4"
-        v-html="compareSuggestion"
-      ></div>
-    </div>
-    <page-title>
-      <template #icon>
-        <img
-          src="@/assets/riskAnalysis/icon-overflow.png"
-          alt=""
-          class="h-full"
-        />
-      </template>
-      <span>{{ "重大疾病风险概览" }}</span>
-    </page-title>
-    <div v-for="(item, index) in overViewList" :key="index">
-      <div class="break-inside-avoid mb-12">
-        <sub-title :type="rankLabel[item.rank].label">
-          <span>{{ item.title }}</span>
-        </sub-title>
-        <SectionText :type="rankLabel[item.rank].label">{{
-          item.note
-        }}</SectionText>
-      </div>
-
-      <table
-        border="0"
-        v-if="item.children.length"
-        class="border-collapse w-full mb-4 text-sm"
-      >
-        <tr class="page-break-avoid-auto page-break-inside-avoid">
-          <td
-            v-for="(column, columnIndex) in riskTableHeader[item.rank] || [
-              '疾病名称',
-              '患病风险',
-              '重要已知风险因素',
-              '对应科室'
-            ]"
-            :key="columnIndex"
-            class="border border-gray-200 px-2 h-[48px] whitespace-nowrap"
-            :class="rankLabel[item.rank]?.thClass"
-          >
-            {{ column }}
-          </td>
-        </tr>
-        <tr
-          v-for="(child, childIdx) in item.children"
-          :key="childIdx"
-          class="page-break-inside-avoid"
-        >
-          <td class="border border-gray-200">
-            <div class="px-2 py-3">
-              {{ child.name }}
-            </div>
-          </td>
-          <td class="border border-gray-200">
-            <div class="px-2 py-3 whitespace-nowrap">
-              <span :class="riskDegreeLabel[child.riskDegree]?.class">{{
-                // riskDegreeLabel[child.riskDegree].label
-                child.riskDesc
-              }}</span>
-            </div>
-          </td>
-          <template v-if="!item.rank">
-            <td class="border border-gray-200">
-              <div class="px-2 py-3">遵医嘱治疗</div>
-            </td>
-          </template>
-          <template v-else-if="riskTableHeader[item.rank]">
-            <td class="border border-gray-200">
-              <div class="px-2 py-3">
-                {{
-                  Array.isArray(child.recommendItems)
-                    ? child.recommendItems.join()
-                    : child.recommendItems
-                }}
-              </div>
-            </td>
-          </template>
-          <td v-else class="border border-gray-200">
-            <div class="px-2 py-3">
-              <div
-                v-for="(know, knowIdx) in child.knownFactors"
-                :key="knowIdx"
-                class=""
-              >
-                <span class="align-middle">{{ know.itemName }}:</span>
-                <span class="align-middle">{{
-                  Array.isArray(know.value) ? know.value.join() : know.value
-                }}</span>
-                <el-icon
-                  v-if="know.mark > 0"
-                  class="inline-block align-middle w-4 h-4 text-red-600"
-                  ><Top />
-                </el-icon>
-                <el-icon
-                  v-if="know.mark < 0"
-                  class="inline-block align-middle w-4 h-4 text-green-600"
-                  ><Bottom />
-                </el-icon>
-              </div>
-            </div>
-          </td>
-          <td class="border border-gray-200">
-            <div class="px-2 py-3">
-              {{
-                Array.isArray(child.department)
-                  ? child.department.join("/")
-                  : child.department || "/"
-              }}
-            </div>
-          </td>
-        </tr>
-      </table>
-      <div
-        v-else
-        class="break-inside-avoid flex flex-col items-center justify-center py-6 mb-4 border border-solid border-gray-200 rounded-b"
-      >
-        <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-        <div class="text-gray-500 text-xs text-center mt-4">暂无分析数据</div>
-      </div>
-    </div>
-    <el-empty v-if="!overViewList?.length" description="暂无数据"></el-empty>
-
-    <component
-      v-if="
-         route.query.archivesId && HorizontalContrast
-      "
-      :is="HorizontalContrast"
-      :archivesId="route.query.archivesId"
-      :hideCtrl="true"
-    >
-      <template #title1>
-        <page-title>
-          <template #icon>
-            <img
-              src="@/assets/riskAnalysis/icon-tumor.png"
-              alt=""
-              class="h-full"
-            />
-          </template>
-          <span>疾病风险评估对比及趋势</span>
-        </page-title>
-      </template>
-      <!-- <template #title2>
-        <page-title class="page-break-avoid-auto">
-          <template #icon>
-            <img
-              src="@/assets/riskAnalysis/icon-tumor.png"
-              alt=""
-              class="h-full"
-            />
-          </template>
-          <span>异常项目横向对比</span>
-        </page-title>
-      </template> -->
-    </component>
-    <UserDataAnalysisEvaluate
-      v-for="(item, index) in 3"
-      :key="index"
-      :classification="index + 1"
-    />
-    <template v-if="suggestion">
-      <page-title :bg="['#1DB198', '#7DFCBC']">
-        <template #icon>
-          <img
-            src="@/assets/riskAnalysis/icon-interpretation.png"
-            alt=""
-            class="h-full"
-          />
-        </template>
-        <span>个性化健康建议</span>
-      </page-title>
-      <div
-        v-if="suggestion"
-        class="relative mb-4 rounded p-4 text-gray-800 leading-6"
-      >
-        <div v-html="suggestion"></div>
-      </div>
-      <div
-        v-else
-        class="break-inside-avoid flex flex-col items-center justify-center py-6 mb-4"
-      >
-        <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-        <div class="text-gray-500 text-xs text-center mt-4">暂无分析数据</div>
-      </div>
-    </template>
-    <!-- <template v-if="props.needHorizontal && compareSuggestionStatus == 4">
-      <page-title :bg="['#1DB198', '#7DFCBC']">
-        <template #icon>
-          <img
-            src="@/assets/riskAnalysis/icon-interpretation.png"
-            alt=""
-            class="h-full"
-          />
-        </template>
-        <span>综合个性化健康建议</span>
-      </page-title>
-      <div class="relative mb-4 rounded p-4 text-gray-800 leading-6">
-        <div v-html="compareSuggestion"></div>
-      </div>
-    </template> -->
-  </div>
-</template>
-<script setup>
-import {
-  computed,
-  shallowRef,
-  watch,
-  ref,
-  nextTick,
-  inject,
-  reactive,
-  onMounted,
-  provide,
-  defineAsyncComponent
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { ElMessage, ElMessageBox } from "element-plus";
-import { deduplicateArrayByKeys } from "@/utils";
-import dayjs from "dayjs";
-import PageTitle from "@/components/PageTitle.vue";
-import SubTitle from "@/components/SubTitle.vue";
-import SectionText from "@/components/SectionText.vue";
-import { Top, Bottom } from "@element-plus/icons-vue";
-import UserDataAnalysisEvaluate from "./UserDataAnalysisEvaluate.vue";
-
-const HorizontalContrast = defineAsyncComponent(() =>
-  import("./HorizontalContrast.vue")
-);
-
-const [route, router] = [useRoute(), useRouter()];
-const props = defineProps({
-  needHorizontal: false
-});
-const riskDegreeToRank = {
-  0: [4],
-  1: [3],
-  2: [2],
-  3: [1],
-  4: [0]
-};
-const riskTableHeader = {
-  0: ["疾病名称", "患病风险", "建议", "对应科室"],
-  3: [
-    "疾病名称",
-    "患病风险",
-    // '建议检查项目',
-    // '建议就医时间',
-    "建议随访项目",
-    // '建议随访时间',
-    "对应科室"
-  ],
-  4: [
-    "疾病名称",
-    "患病风险",
-    "建议完善项目",
-    // '建议完善时间',
-    "对应科室"
-  ]
-};
-const riskDegreeLabel = {
-  4: {
-    label: "已确诊",
-    class: "font-bold text-violet-500"
-  },
-  3: {
-    label: "有明显风险",
-    class: "font-bold text-red-600"
-  },
-  2: {
-    label: "有一定风险",
-    class: "font-bold text-yellow-500"
-  },
-  1: {
-    label: "暂未发现风险",
-    class: "text-green-500"
-  },
-  0: {
-    label: "暂未发现风险",
-    class: "text-gray-500"
-  }
-};
-const rankLabel = {
-  0: { label: "diagnosis", thClass: "text-violet-800 bg-violet-200" },
-  1: { label: "danger", thClass: "text-red-500 bg-red-50" },
-  2: { label: "warning", thClass: "text-yellow-600 bg-yellow-100" },
-  3: { label: "success", thClass: "text-green-800 bg-green-200" },
-  4: { label: "primary", thClass: "text-blue-800 bg-blue-200" }
-};
-
-const resultRawJson = inject("resultRawJson");
-// const latestReport = inject("latestReport");
-const compareReportDetail = inject("compareReportDetail");
-const suggestion = inject("suggestion");
-const compareSuggestion = inject("compareSuggestion");
-const compareSuggestionStatus = inject("compareSuggestionStatus");
-const overViewList = ref();
-
-const formatOverView = () => {
-  overViewList.value = (
-    resultRawJson.value?.result?.reportConfig.reportPreviewCfg.sectionContent ||
-    []
-  )
-    .map(v => {
-      const tempItem = { ...v, children: [] };
-      const children = (riskDegreeToRank[v.rank] || [])
-        .map(riskDegree => {
-          return (resultRawJson.value?.result?.majorDisease || [])
-            .filter(v2 => v2.riskDegree == riskDegree)
-            .sort((a, b) => b.riskDegree - a.riskDegree);
-        })
-        .flat();
-      tempItem.children = deduplicateArrayByKeys(children, ["nodeId"]);
-      return tempItem;
-    })
-    .filter(v => v.children.length);
-  console.log("overViewList.value", overViewList.value, resultRawJson.value);
-  setupZones(resultRawJson.value?.result?.majorDisease || []);
-};
-
-const zones = ref([]);
-const riskDegreeMap = [4, 3, 2, 0, 1];
-const notificationTimeMap = [365, 30, 1, 0];
-
-const setupZones = healthConditions => {
-  // 创建5x5的分区,表示不同的优先度和风险等级
-  zones.value = [];
-
-  // 初始化分区数据
-  for (const risk of riskDegreeMap) {
-    zones.value.push([]);
-    for (const notificationTime of notificationTimeMap) {
-      zones.value.at(-1).push({
-        riskDegree: risk,
-        notificationTime: notificationTime,
-        conditions: [], // 初始为空,将在后续填充
-        style: {
-          // backgroundColor,
-          // textColor,
-        }
-      });
-    }
-  }
-
-  // 将健康条件分配到对应的分区
-  healthConditions.forEach(condition => {
-    zones.value.forEach((row, rowIdx) => {
-      const zone = row.find(
-        z =>
-          z.riskDegree == condition.riskDegree &&
-          z.notificationTime == condition.notificationTime
-      );
-      if (zone) {
-        zone.conditions.push(condition);
-      }
-    });
-  });
-  console.log(zones);
-};
-watch(
-  () => resultRawJson.value,
-  v => {
-    console.log("resultRawJson.value", resultRawJson.value, v);
-    formatOverView();
-  },
-  { immediate: true }
-);
-</script>
-<style lang="scss">
-.chart-background {
-  background: linear-gradient(to top right, #4fc46b, #c2d85f, #f3b475, #f06a5f);
-
-  border-top-right-radius: 10px;
-  position: relative;
-}
-
-/* X轴和Y轴箭头头部的样式 */
-.arrow-y-head {
-  width: 0;
-  height: 0;
-  border-left: 5px solid transparent;
-  border-right: 5px solid transparent;
-  border-bottom: 10px solid #333;
-  position: absolute;
-  top: -10px;
-  left: -5px;
-}
-
-.arrow-x-head {
-  width: 0;
-  height: 0;
-  border-top: 5px solid transparent;
-  border-bottom: 5px solid transparent;
-  border-left: 10px solid #333;
-  position: absolute;
-  top: -5px;
-  right: -10px;
-}
-</style>

+ 0 - 112
src/views/healthManagement/components/ManagementPlan.vue

@@ -1,112 +0,0 @@
-<template>
-  <div class="p-4" style="height: 80vh">
-    <el-card shadow="never">
-      <div class="text-center" v-if="!state.list.length">
-        <el-empty />
-        <Auth value="healthManage">
-          <el-button type="primary" plain class="mb-10" @click="handleAdd"
-            >添加管理计划</el-button
-          >
-        </Auth>
-      </div>
-      <div v-else>
-        <ComponentManagementPlanDetail
-          :list="state?.list"
-          @onChangeStatus="onChangeStatus"
-          @onEdit="onEdit"
-          @onEvaluate="onEvaluate"
-          @onDelete="onDelete"
-        />
-      </div>
-    </el-card>
-    <ComponentDialogSelectIllness v-model:show="state.visible" />
-  </div>
-</template>
-<script setup>
-import { request } from "@/utils";
-import { reactive, computed } from "vue";
-
-import { useRouter, useRoute } from "vue-router";
-const [route, router] = [useRoute(), useRouter()];
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-
-import ComponentDialogSelectIllness from "./DialogSelectIllness.vue";
-import ComponentManagementPlanDetail from "./ManagementPlanDetail.vue";
-import { ElMessage } from "element-plus";
-const state = reactive({
-  visible: false,
-  list: []
-});
-
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const getDetail = () => {
-  request
-    .get("/platformApi/dataService/diseaseManage/detail", {
-      params: {
-        archiveId: currentArchiveId.value
-      }
-    })
-    .then(resp => {
-      const response = resp.data;
-      response?.forEach(item => {
-        item.indicator = (item.indicator || []).map(v => {
-          v.expand = true;
-          v.list = v.list.map(v2 => {
-            const dateList = {};
-            v2.list.forEach(v3 => {
-              if (dateList[v3.date]) {
-                dateList[v3.date].push(v3);
-              } else {
-                dateList[v3.date] = [v3];
-              }
-              v2.list = Object.values(dateList);
-            });
-            return v2;
-          });
-          return v;
-        });
-      });
-      state.list = response;
-      console.log("state.list", state.list);
-    });
-};
-const handleAdd = () => {
-  state.visible = true;
-};
-const onEdit = index => {
-  router.push(
-    `/healthManagement/evaluate?illnessId=${state.list[index]?.diseaseId}&name=${state.list[index]?.disease}&id=${state.list[index]?.id}&archivesId=${currentArchiveId.value}&type=edit&level=${state.list[index]?.level}`
-  );
-};
-const onEvaluate = index => {
-  router.push(
-    `/healthManagement/evaluate?illnessId=${state.list[index]?.diseaseId}&name=${state.list[index]?.disease}&id=${state.list[index]?.id}&archivesId=${currentArchiveId.value}&type=evaluate&level=${state.list[index]?.level}`
-  );
-};
-const onDelete = index => {
-  request
-    .post("/platformApi/dataService/diseaseManage/delete", {
-      id: state.list[index]?.id
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      getDetail();
-    });
-};
-const onChangeStatus = row => {
-  request
-    .post("/platformApi/dataService/diseaseManage/update/status", {
-      id: row.id,
-      status: row.status ? 0 : 1
-    })
-    .then(resp => {
-      ElMessage.success(resp.message);
-      getDetail();
-    });
-};
-getDetail();
-</script>

+ 0 - 437
src/views/healthManagement/components/ManagementPlanDetail.vue

@@ -1,437 +0,0 @@
-<template>
-  <div>
-    <el-button type="primary" @click="handleAddPlan">添加管理计划</el-button>
-    <!-- <el-button type="primary" @click="handleBacklog">待办事件管理</el-button> -->
-    <div class="mt-4">
-      <div v-for="(item, index) in props.list" :key="index" class="mb-2">
-        <el-card>
-          <template #header>
-            <div class="flex items-center justify-between">
-              <div class="flex items-center">
-                <el-tag class="mr-2" v-if="item.levelName">{{
-                  formatLevel(item.levelName)
-                }}</el-tag>
-                <!-- <h3>管理疾病名称: {{ item.disease }}</h3> -->
-                <h3>{{ item.groupName }}</h3>
-              </div>
-              <div class="flex items-center">
-                <div v-if="!item.status">
-                  <h4
-                    v-if="
-                      moment().format('YYYY-MM-DD') ==
-                      item?.nextTime?.split(' ')[0]
-                    "
-                    style="color: #67c23a"
-                  >
-                    今天({{ item.nextTime?.split(" ")[0] }})需要进行评估
-                  </h4>
-                  <h4
-                    v-else-if="
-                      moment().valueOf() >
-                      moment(item?.nextTime?.split(' ')[0].valueOf())
-                    "
-                    style="color: #f56c6c"
-                  >
-                    已超时{{
-                      Number(0 - timeDiffer(item?.nextTime?.split(" ")[0]))
-                    }}天({{ item.nextTime?.split(" ")[0] }} )请尽快评估
-                  </h4>
-                  <h4 v-else>
-                    {{ timeDiffer(item?.nextTime?.split(" ")[0]) }}天后({{
-                      item?.nextTime?.split(" ")[0]
-                    }})将进行下一次评估
-                  </h4>
-                </div>
-                <div v-else>
-                  <h3>管理已暂停</h3>
-                </div>
-
-                <Auth value="healthManage">
-                  <el-button
-                    class="ml-3"
-                    type="primary"
-                    @click="emits('onEvaluate', index)"
-                    >评估</el-button
-                  >
-                </Auth>
-              </div>
-            </div>
-          </template>
-          <div>
-            <el-row :gutter="10">
-              <el-col :span="12">
-                <h4>健康状况趋势</h4>
-                <!-- <div class="left-chart" :id="`chart-${index}`"></div> -->
-                <div class="bg-white h-64 rounded shadow">
-                  <Chart ref="chartRef" />
-                </div>
-              </el-col>
-              <el-col :span="12">
-                <h4>
-                  {{ item.createdAt.split(" ")[0] }}
-                  至
-                  {{ item.nextTime?.split(" ")[0] }} 期间(共{{
-                    diffTime(
-                      item.nextTime?.split(" ")[0],
-                      item.createdAt.split(" ")[0]
-                    ) || 1
-                  }}天)管理目标
-                </h4>
-                <div>
-                  <el-text v-if="!item.status">{{ item.target }}</el-text>
-                  <el-empty v-else description="该管理已暂停" />
-                </div>
-              </el-col>
-            </el-row>
-            <el-row class="mt-4" v-if="item.indicator?.length">
-              <el-col :span="24">
-                <h4>关键指标追踪</h4>
-
-                <div class="py-4 space-y-4 pr-4">
-                  <div
-                    v-for="(item, index) in item.indicator"
-                    :key="index"
-                    class="shadow"
-                  >
-                    <div
-                      class="cursor-pointer py-2 px-4 flex items-center justify-between"
-                      :class="{
-                        'bg-gray-50': !item.expand,
-                        'bg-blue-50 text-blue-700': item.expand
-                      }"
-                      @click="item.expand = !item.expand"
-                    >
-                      <span>{{ item.name }}</span>
-                      <ArrowUp class="w-4 text-gray-500" v-if="!item.expand" />
-                      <ArrowDown class="w-4 text-gray-500" v-else />
-                    </div>
-                    <div class="w-full overflow-x-auto">
-                      <table
-                        v-if="item.expand"
-                        class="min-w-full bg-white text-gray-700 table-fixed"
-                      >
-                        <tr class="font-bold">
-                          <td
-                            class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-                          >
-                            项目
-                          </td>
-                          <td
-                            class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-                            v-for="(col, index) in item.list?.[0]?.list"
-                            :key="index"
-                          >
-                            {{
-                              dayjs(col[0].date * 1000).format(
-                                "YYYY-MM-DD HH:mm:ss"
-                              )
-                            }}
-                          </td>
-                        </tr>
-                        <tr
-                          v-for="(child, childIdx) in item.list"
-                          :key="childIdx"
-                        >
-                          <td
-                            class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-                          >
-                            {{ child.name }}
-                          </td>
-                          <td
-                            v-for="(col, colIdx) in child.list"
-                            :key="colIdx"
-                            class="border border-solid border-gray-100"
-                          >
-                            <div class="p-2 text-sm">
-                              <div
-                                v-for="(subCol, subColIdx) in col"
-                                :key="subColIdx"
-                                class="inline-flex items-center"
-                              >
-                                <span class="align-middle"
-                                  >{{ subCol.value
-                                  }}{{
-                                    subCol.unit && subCol.unit != "-"
-                                      ? subCol.unit
-                                      : ""
-                                  }}
-                                </span>
-                                <!-- {{  subCol }} -->
-                                <el-icon
-                                  v-if="subCol.mark > 0"
-                                  class="inline-block align-middle w-4 text-red-600"
-                                  ><Top />
-                                </el-icon>
-                                <el-icon
-                                  v-if="subCol.mark < 0"
-                                  class="inline-block align-middle w-4 text-green-600"
-                                  ><Bottom />
-                                </el-icon>
-                                <template v-if="subCol.reference">
-                                  <el-tooltip>
-                                    <QuestionFilled
-                                      class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                                    />
-                                    <template #content>
-                                      <div class="text-sm">
-                                        参考范围:{{ subCol.reference }}
-                                      </div>
-                                    </template>
-                                  </el-tooltip>
-                                </template>
-                              </div>
-                            </div>
-                          </td>
-                        </tr>
-                      </table>
-                    </div>
-                  </div>
-                  <el-empty v-if="!list.length" />
-                </div>
-              </el-col>
-            </el-row>
-          </div>
-          <template #footer>
-            <div class="flex justify-between">
-              <div>
-                <el-button
-                  type="primary"
-                  link
-                  :icon="Setting"
-                  @click="handleEditItem(index)"
-                  >阶段管理设置</el-button
-                >
-                <el-button
-                  type="primary"
-                  link
-                  :icon="Clock"
-                  @click="handleHistory(index)"
-                  >评估历史详情</el-button
-                >
-              </div>
-              <div class="flex-right">
-                <el-button
-                  v-if="item.status"
-                  type="primary"
-                  link
-                  :icon="VideoPlay"
-                  style="color: green"
-                  @click="handleChangeStatus(item)"
-                  >恢复管理</el-button
-                >
-                <el-button
-                  v-else
-                  type="primary"
-                  link
-                  :icon="VideoPause"
-                  style="color: red"
-                  @click="handleChangeStatus(item)"
-                  >暂停管理</el-button
-                >
-
-                <el-popconfirm
-                  title="确定要删除此管理计划吗"
-                  @confirm="emits('onDelete', index)"
-                >
-                  <template #reference>
-                    <el-button
-                      type="primary"
-                      link
-                      :icon="Delete"
-                      style="color: red"
-                      >删除</el-button
-                    >
-                  </template>
-                </el-popconfirm>
-              </div>
-            </div>
-          </template>
-        </el-card>
-      </div>
-    </div>
-    <ComponentDialogSelectIllness v-model:show="state.visibleAdd" />
-    <ComponentDialogBacklog v-model:show="state.visibleBacklog" />
-    <el-dialog title="评估历史详情" v-model="state.visibleHistory">
-      <div>
-        <ComponentAssessmentHistory
-          :list="transformDataExpand([state.currentItem], 'histories')"
-          ref="historyRef"
-        />
-      </div>
-    </el-dialog>
-  </div>
-</template>
-<script lang="ts" setup>
-import { ref, reactive, defineProps, defineEmits } from "vue";
-import * as echarts from "echarts";
-import { nextTick } from "process";
-import moment from "moment";
-import dayjs from "dayjs";
-import {
-  QuestionFilled,
-  ArrowUp,
-  ArrowDown,
-  Top,
-  Bottom
-} from "@element-plus/icons-vue";
-
-import ComponentDialogSelectIllness from "./DialogSelectIllness.vue";
-// import ComponentDialogBacklog from "./DialogBacklog.vue";
-import ComponentAssessmentHistory from "./AssessmentHistory.vue";
-import Chart from "@/components/Chart.vue";
-
-import { ElMessage, ElMessageBox } from "element-plus";
-
-import {
-  Setting,
-  Clock,
-  VideoPause,
-  VideoPlay,
-  Delete
-} from "@element-plus/icons-vue";
-import { request, transformDataExpand, timeDiffer } from "@/utils";
-
-const props = defineProps({
-  list: Array,
-  default: () => []
-});
-const emits = defineEmits("onChangeStatus", "onEdit", "onEvaluate", "onDelete");
-const state = reactive({
-  visibleAdd: false,
-  visibleBacklog: false,
-  visibleHistory: false,
-  currentItem: {}
-});
-const chartRef = ref();
-const historyRef = ref();
-const formatLevel = level => {
-  const map = new Map([
-    ["一级预防", "1级预防"],
-    ["二级预防", "2级预防"],
-    ["三级预防", "3级预防"],
-    ["四级预防", "4级预防"]
-  ]);
-  return map.get(level);
-};
-const initChart = index => {
-  props.list.map((item, i) => {
-    const list = transformDataExpand([item], "histories");
-    // list.forEach(v => {
-    //   if (v.effect?.name == "缺乏评估数据") {
-    //     v.effect["程度"] = 5;
-    //   }
-    // });
-    chartRef.value[i]?.setOption({
-      title: {
-        text: "",
-        top: "10",
-        left: "10"
-      },
-      grid: {
-        left: "5%",
-        right: "5%",
-        bottom: "15%"
-      },
-      // dataZoom: [
-      //   {
-      //     type: "slider", //slider表示有滑动块的,
-      //     show: true,
-      //     xAxisIndex: [0], //表示x轴折叠
-      //     start: 1, //数据窗口范围的起始百分比,表示1%
-      //     end: 35, //数据窗口范围的结束百分比,表示35%坐标
-      //     bottom: "20"
-      //   }
-      // ],
-      xAxis: {
-        type: "category",
-        data: list.map(v => v.createdAt).reverse(),
-        axisLabel: {
-          formatter: params => {
-            return params?.split(" ")[0] + "\n" + params?.split(" ")[1];
-          }
-        }
-      },
-      yAxis: {
-        type: "value",
-        axisLine: { show: false },
-        axisTick: { show: false },
-        axisLabel: { show: false }
-      },
-      series: [
-        {
-          data: list.map(v => Number(v.effect["程度"])).reverse(),
-          type: "line",
-          itemStyle: {
-            normal: {
-              // 这里就可以实现,配置柱状图的颜色
-              color: function (params) {
-                const colorList = [
-                  "#ccc",
-                  "#c101c1",
-                  "#FCCE10",
-                  "#E87C25",
-                  "#27727B",
-                  "#D7504B"
-                ];
-                return colorList[params.value];
-              }
-            }
-          },
-          label: {
-            show: true,
-            position: "top",
-            formatter: params => {
-              return list.find(v => v.effect["程度"] == params.value)?.effect
-                ?.name;
-            }
-          },
-          smooth: true
-        }
-      ]
-    });
-  });
-};
-const diffTime = (end, start) => {
-  return moment(end).diff(moment(start), "day");
-};
-const handleAddPlan = () => {
-  state.visibleAdd = true;
-};
-const handleBacklog = () => {
-  state.visibleBacklog = true;
-};
-const handleHistory = index => {
-  state.currentItem = props.list[index];
-  state.visibleHistory = true;
-  console.log(historyRef.value);
-
-  historyRef.value?.initChart();
-};
-const handleChangeStatus = row => {
-  ElMessageBox.confirm(
-    row.status
-      ? "确定继续次疾病的管理?"
-      : "确定要暂停这个管理吗?暂停后不可再进行评估",
-    "",
-    {
-      distinguishCancelAndClose: true,
-      confirmButtonText: "确定",
-      cancelButtonText: "取消"
-    }
-  )
-    .then(async () => {
-      emits("onChangeStatus", row);
-    })
-    .catch(err => {});
-};
-const handleEditItem = index => {
-  emits("onEdit", index);
-};
-nextTick(initChart);
-</script>
-<style scoped lang="scss">
-.left-chart {
-  width: 500px;
-  height: 400px;
-}
-</style>

+ 0 - 145
src/views/healthManagement/components/PlanArchives.vue

@@ -1,145 +0,0 @@
-<template>
-  <div
-    class="bg-white border-0 mb-4 sticky top-0 border-gray-100 border-solid border-b"
-  >
-    <div
-      v-for="(item, index) in formList"
-      class="hover:bg-gray-50 cursor-pointer p-4 w-fit border-b border-solid text-gray-500"
-      :class="{
-        'text-gray-800 bg-gray-50 border-b-2 border-blue-400':
-          curForm == item.id
-      }"
-      :key="item.id"
-      :index="String(item.id)"
-      @click="curForm = item.id"
-    >
-      <div class="flex items-center">
-        <span>{{ item.name }}</span>
-      </div>
-    </div>
-  </div>
-  <div class="p-4">
-    <div class="px-4 pb-4">
-      <ArchivesModule is-plat :module-id="curForm" :form="form" />
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  ref,
-  shallowRef,
-  provide,
-  nextTick,
-  watch,
-  inject,
-  defineAsyncComponent
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-
-import { ElMessage } from "element-plus";
-import { request, parseJsonData } from "@/utils";
-const ArchivesModule = defineAsyncComponent(() =>
-  import("@/views/dataCenter/components/ArchivesModule.vue")
-);
-const refreshArchives = inject("refreshArchives");
-const route = useRoute();
-const router = useRouter();
-const formList = ref([]);
-const curForm = ref();
-const getFormTemplate = async () => {
-  const { data } = await request.get(
-    `/archivesService/mechanism/form/template/detail`,
-    {
-      params: {
-        archivesId: route.query.archivesId
-      }
-    }
-  );
-  formList.value = data.template.forms?.map(v => {
-    return {
-      icon: v.icon,
-      selectIcon: v.icon,
-      name: v.name,
-      id: v.id,
-      value: v.id
-    };
-  });
-  if (formList.value?.length) {
-    curForm.value = formList.value[0].id;
-    getFormDetail();
-  }
-};
-getFormTemplate();
-const form = ref();
-
-const transferRawJson = ref();
-provide("transferRawJson", transferRawJson);
-
-const getFormDetail = async () => {
-  const { data } = await request.get(`/archivesService/mechanism/form/detail`, {
-    params: {
-      archivesId: route.query.archivesId,
-      formId: curForm.value,
-      needCheckItemId: 1
-    }
-  });
-  form.value = data.detail;
-  getFillFormData();
-};
-provide("refreshFormDetail", getFormDetail);
-const getFillFormData = async () => {
-  let ids = [];
-  form.value.fields.forEach(v => {
-    if (v.fields?.length) {
-      v.fields.forEach(filed => {
-        if (filed.extra?.subjectIds) {
-          ids.push(...filed.extra.subjectIds);
-        } else {
-          filed.extra?.sn && ids.push(filed.extra?.sn);
-        }
-      });
-    }
-
-    if (v.extra?.subjectIds) {
-      ids.push(...v.extra.subjectIds);
-    } else {
-      v.extra?.sn && ids.push(v.extra.sn);
-    }
-  });
-  console.log("ids", ids);
-  ids = [...new Set(ids)];
-  if (!ids.length) return;
-  const { data } = await request.post(
-    `/archivesService/mechanism/form/data/query`,
-    {
-      archivesId: route.query.archivesId,
-      ids
-    }
-  );
-  transferRawJson.value = (data.list || []).map(v => {
-    return {
-      ...v,
-      answer: v.returnAnswer
-    };
-  });
-  console.log("transferRawJson", transferRawJson.value);
-};
-
-const submitSimpleFormData = async (answers, close) => {
-  const req = {
-    archivesId: route.query.archivesId,
-    answers
-  };
-  console.log(req);
-  await request.post("/archivesService/mechanism/form/submit", req);
-  ElMessage.success("操作成功");
-  close();
-  getFormDetail();
-  refreshArchives && refreshArchives();
-};
-provide("submitSimpleFormData", submitSimpleFormData);
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 231
src/views/healthManagement/components/PlanCheckData.vue

@@ -1,231 +0,0 @@
-<template>
-  <!-- <div class="bg-[#f0f2f5] sticky z-10 top-0 h-4"></div> -->
-  <div
-    class="bg-white p-4 sticky z-10 top-0 flex space-x-2 items-center shadow-sm mr-4 flex-wrap"
-  >
-    <div class="mb-2">
-      <el-date-picker
-        v-model="filterDate"
-        type="daterange"
-        format="YYYY/MM/DD"
-        value-format="YYYY-MM-DD"
-        start-placeholder="请选择"
-        end-placeholder="请选择"
-      />
-    </div>
-    <el-select
-      v-model="filter.project"
-      class="mb-2"
-      multiple
-      filterable
-      clearable
-      collapse-tags
-      placeholder="请选择检查项目"
-      @change="searchRelateNodes"
-    >
-      <el-option
-        v-for="(item, index) in projects"
-        :key="index"
-        :label="item.name"
-        :value="item.id"
-      ></el-option>
-    </el-select>
-
-    <el-select
-      v-model="filter.nodes"
-      class="mb-2"
-      multiple
-      filterable
-      clearable
-      collapse-tags
-      :disabled="!filter.project.length"
-      placeholder="请选择"
-    >
-      <el-option
-        v-for="(item, index) in nodes"
-        :key="index"
-        :label="item.name"
-        :value="item.id"
-      ></el-option>
-    </el-select>
-    <el-button class="mb-2" type="primary" @click="search">搜索</el-button>
-  </div>
-  <div class="py-4 space-y-4 pr-4">
-    <div v-for="(item, index) in list" :key="index" class="shadow">
-      <div
-        class="cursor-pointer py-2 px-4 flex items-center justify-between"
-        :class="{
-          'bg-gray-50': !item.expand,
-          'bg-blue-50 text-blue-700': item.expand
-        }"
-        @click="item.expand = !item.expand"
-      >
-        <span>{{ item.name }}</span>
-        <ArrowUp class="w-4 text-gray-500" v-if="!item.expand" />
-        <ArrowDown class="w-4 text-gray-500" v-else />
-      </div>
-      <div class="w-full overflow-x-auto">
-        <table
-          v-if="item.expand"
-          class="min-w-full bg-white text-gray-700 table-fixed"
-        >
-          <tr class="font-bold">
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-            >
-              项目
-            </td>
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-              v-for="(col, index) in item.list?.[0]?.list"
-              :key="index"
-            >
-              {{ dayjs(col[0].date * 1000).format("YYYY-MM-DD HH:mm:ss") }}
-            </td>
-          </tr>
-          <tr v-for="(child, childIdx) in item.list" :key="childIdx">
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-            >
-              {{ child.name }}
-            </td>
-            <td
-              v-for="(col, colIdx) in child.list"
-              :key="colIdx"
-              class="border border-solid border-gray-100"
-            >
-              <div class="p-2 text-sm">
-                <div v-for="(subCol, subColIdx) in col" :key="subColIdx" class="inline-flex items-center">
-                  <span class="align-middle"
-                    >{{ subCol.value
-                    }}{{ subCol.unit && subCol.unit != "-" ? subCol.unit : "" }}
-                  </span>
-                  <!-- {{  subCol }} -->
-                  <el-icon
-                    v-if="subCol.mark > 0"
-                    class="inline-block align-middle w-4 text-red-600"
-                    ><Top />
-                  </el-icon>
-                  <el-icon
-                    v-if="subCol.mark < 0"
-                    class="inline-block align-middle w-4 text-green-600"
-                    ><Bottom />
-                  </el-icon>
-                  <template v-if="subCol.reference">
-                    <el-tooltip>
-                      <QuestionFilled
-                        class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                      />
-                      <template #content>
-                        <div class="text-sm">参考范围:{{ subCol.reference }}</div>
-                      </template>
-                    </el-tooltip>
-                  </template>
-                </div>
-              </div>
-            </td>
-          </tr>
-        </table>
-      </div>
-    </div>
-    <el-empty v-if="!list.length"></el-empty>
-  </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, watch, provide } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import { useRoute, useRouter } from "vue-router";
-
-import { request } from "@/utils";
-import dayjs from "dayjs";
-import { QuestionFilled, ArrowUp, ArrowDown, Top, Bottom } from "@element-plus/icons-vue";
-const route = useRoute();
-const router = useRouter();
-const filter = ref({
-  project: [],
-  nodes: [],
-  startTime: "",
-  endTime: ""
-});
-const filterDate = ref(["", ""]);
-watch(
-  () => filterDate.value,
-  d => {
-    console.log(d);
-    if (d) {
-      [filter.value.startTime, filter.value.endTime] = d;
-    }
-  }
-);
-const projects = ref([]);
-const nodes = ref([]);
-const list = ref([]);
-const search = async () => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/query",
-    {
-      archivesId: route.query.archivesId,
-      itemIds: filter.value.project,
-      nodeIds: filter.value.nodes,
-      date: filterDate.value.filter(v => v)
-    }
-  );
-  list.value = (data.list || []).map(v => {
-    v.expand = true;
-    v.list = v.list.map(v2 => {
-      const dateList = {};
-      v2.list.forEach(v3 => {
-        if (dateList[v3.date]) {
-          dateList[v3.date].push(v3);
-        } else {
-          dateList[v3.date] = [v3];
-        }
-        v2.list = Object.values(dateList);
-      });
-      return v2;
-    });
-    return v;
-  });
-  console.log(list.value)
-};
-
-const recognitionType = ["医学检查项目", "身体物质/部位"];
-
-const relatedRelationship = ["异常属于", "可检测"];
-const searchNodes = async (type = 0, name = "") => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/query",
-    {
-      archivesId: route.query.archivesId,
-      itemIds: [],
-      nodeIds: [],
-      date: []
-    }
-  );
-  projects.value = data.list || []
-};
-const searchRelateNodes = async () => {
-  // const { data } = await request.get(`/graphService/open/node/related`, {
-  //   params: {
-  //     id,
-  //     relationship: relatedRelationship[relationship]
-  //   }
-  // });
-  // nodes.value = data;
-
-  nodes.value = filter.value.project
-    .map(id => {
-      return projects.value.find(v => v.id == id)?.list || [];
-    })
-    .flat();
-};
-
-const init = async () => {
-  await searchNodes();
-  search();
-};
-init();
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 24
src/views/healthManagement/components/PreviewSetItemTable.vue

@@ -1,24 +0,0 @@
-<template>
-  <div>
-    <el-table :data="data" style="width: 100%" v-bind="$attrs">
-      <el-table-column prop="prop" label="完成时间">
-        <template #default="{ row }">
-          {{ previewTime(row.frequencyType, row.duration)?.label }}
-        </template>
-      </el-table-column>
-      <el-table-column prop="prop" label="完成时间">
-        <template #default="{ row }">
-          {{ previewTime(row.frequencyType, row.duration)?.label }}
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-<script lang="ts" setup>
-import { previewTime } from "@/utils/index";
-const props = defineProps({
-  data: {
-    type: Array
-  }
-});
-</script>

+ 0 - 119
src/views/healthManagement/components/ProfileCard.vue

@@ -1,119 +0,0 @@
-<template>
-  <div class="min-w-[320px] space-y-2 text-sm">
-    <div class="bg-white flex items-center">
-      <div class="w-12 h-12">
-        <img
-          :src="archivesInfo?.gender == 1 ? man : woman"
-          round
-          class="w-12 h-12 rounded-full mr-4"
-        />
-      </div>
-      <div class="flex-1 pl-4 space-y-0">
-        <div class="flex items-center">
-          <span>{{ archivesInfo.name }}</span>
-          <div class="flex items-center my-1 ml-2">
-            <div class="flex items-center mr-4">
-              <img src="@/assets/icon-gender.png" alt="" class="w-5 h-5" />
-              <span class="text-sm text-gray-700">{{
-                archivesInfo.gender == 1 ? "男" : "女"
-              }}</span>
-            </div>
-            <div class="flex items-center my-1">
-              <img src="@/assets/icon-birthday.png" alt="" class="w-5 h-5" />
-              <span class="text-sm text-gray-700"
-                >{{ formatAge(archivesInfo.birthday) }}岁</span
-              >
-            </div>
-          </div>
-        </div>
-        <div class="w-full">
-          <div class="flex items-center mb-2">
-            <span>档案号:</span>
-            <span>{{ archivesInfo.id }}</span>
-            <CopyDocument
-              v-if="archivesInfo.id"
-              class="w-4 text-blue-500 cursor-copy ml-1"
-              v-copy="archivesInfo.id"
-            />
-          </div>
-          <div class="flex items-center">
-            <span
-              >联系方式:{{
-                archivesInfo.accounts.find(v => v.type === 1)?.account
-              }}</span
-            >
-            <CopyDocument
-              v-if="archivesInfo?.accounts?.find(v => v.type === 1)?.account"
-              class="w-4 text-blue-500 cursor-copy ml-1"
-              v-copy="archivesInfo.accounts.find(v => v.type === 1)?.account"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-<script lang="ts" setup>
-import { ref, watch } from "vue";
-import { useRoute, useRouter } from "vue-router";
-// import ManagementPlan from "./components/ManagementPlan.vue";
-import {
-  CopyDocument,
-  Fold,
-  ArrowLeft,
-  ArrowRight
-} from "@element-plus/icons-vue";
-import man from "@/assets/icon-man.png";
-import woman from "@/assets/icon-woman.png";
-import {
-  formatAge,
-  parseJsonData,
-  request,
-  transformDataExpand
-} from "@/utils";
-
-const props = defineProps({
-  id: {
-    type: String
-  }
-});
-const archivesInfo = ref({
-  id: "",
-  name: "",
-  avatar: "",
-  gender: 0,
-  birthday: "",
-  mainArchivesId: "",
-  accounts: []
-});
-
-const highRiskDiseaseList = ref([]);
-const recommendValues = ref({
-  medicalHistory: [],
-  medicationStatus: [],
-  susceptibilityGene: []
-});
-const getArchivesDetail = async () => {
-  if (!props.id) return;
-
-  const { data } = await request.get(
-    "/archivesService/mechanism/archives/detail",
-    {
-      params: {
-        archivesId: props.id
-      }
-    }
-  );
-  archivesInfo.value = data.detail;
-  highRiskDiseaseList.value = data.highRiskDiseaseList;
-  recommendValues.value = data.recommendValues;
-};
-watch(
-  () => props.id,
-  () => {
-    console.log("监听成功");
-    getArchivesDetail();
-  },
-  { deep: true, immediate: true }
-);
-</script>

+ 0 - 104
src/views/healthManagement/components/ReturnVisitItem.vue

@@ -1,104 +0,0 @@
-<template>
-  <div>
-    <div class="flex items-center mb-6">
-      回访事项:
-      <el-select
-        v-model="state.node"
-        placeholder="请选择"
-        style="width: 115px"
-        @change="handleSearchrRelatedNode"
-      >
-        <el-option
-          v-for="item in state.nodeList"
-          :label="item.properties.name"
-          :value="item.id"
-          :key="item.id"
-        />
-      </el-select>
-      <el-button type="primary" plain @click="handleAdd" class="ml-2"
-        >确认添加</el-button
-      >
-    </div>
-    <div>
-      <ComponentTableSetItem
-        :tableData="state.tableData"
-        :config="config"
-        @remove="handleRemove"
-      ></ComponentTableSetItem>
-    </div>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request } from "@/utils";
-import { ElMessage } from "element-plus";
-import { onMounted, reactive } from "vue";
-import ComponentTableSetItem from "./TableSetItem.vue";
-const state = reactive({
-  node: "", // 检查项目
-  related: "",
-  nodeList: [],
-  relatedList: [],
-  tableData: []
-});
-const config = {
-  name: { label: "检查项目", prop: "name" },
-  content: { label: "包含的检查内容", prop: "content" },
-  time: { label: "完成时间", prop: "time", width: "300" },
-  timePreview: { label: "完成时间预览", prop: "timePreview" },
-  completeNum: { label: "完成次数", prop: "completeNum" },
-  remark: { label: "备注信息", prop: "remark" },
-  handle: { label: "操作", prop: "handle" }
-};
-const getNodeList = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 999,
-        tag: "医学检查项目"
-      }
-    })
-    .then(resp => {
-      state.nodeList = resp.data.list;
-    });
-};
-const handleAdd = () => {
-  if (!state.node || !state.related) {
-    return ElMessage.error("请选择检查项目");
-  }
-  state.node = "";
-  state.related = "";
-  let config = {
-    name: state.nodeList.find(v => v.id == state.node)?.properties.name,
-    content: state.related,
-    timeType: "day",
-    time: "",
-    timePreview: "",
-    completeNum: "", // 完后次数
-    remark: "",
-    handle: ""
-  };
-  state.tableData.push(config);
-};
-const handleRemove = index => {
-  state.tableData.splice(index, 1);
-};
-const handleSearchrRelatedNode = id => {
-  request
-    .get("/platformApi/graphService/open/node/related", {
-      params: {
-        id: id,
-        relationship: "可检测"
-      }
-    })
-    .then(resp => {
-      state.relatedList = resp.data;
-    });
-};
-const onReset = () => {
-  state.related = "";
-  state.node = "";
-  state.tableData = [];
-  getNodeList();
-};
-onMounted(onReset);
-</script>

+ 0 - 120
src/views/healthManagement/components/RiskWarningReport.vue

@@ -1,120 +0,0 @@
-<template>
-  <div>
-    <el-tabs type="border-card">
-      <el-tab-pane label="最新风险分析结果" lazy>
-        <div class="flex justify-between">
-          <div
-            v-if="detail.startTime && detail.endTime"
-            class="flex items-center text-gray-700 text-sm"
-          >
-            <el-tooltip>
-              <QuestionFilled
-                class="w-4 h-4 inline align-middle cursor-pointer opacity-50 outline-none"
-              />
-              <template #content>
-                <div class="text-sm">
-                  <p>1、系统自动抓取用户上传的最新数据进行分析</p>
-                  <p>
-                    2、某个检查,比如血脂检查,最新的数据是2年前的,那么系统只能认为这份数据为最新数据
-                  </p>
-                  <p>
-                    3、及时上传最新的检查数据,分析的结果更接近当前的身体状况
-                  </p>
-                  <p>
-                    4、系统分析数据检查日期范围为系统抓取的各种检查数据的检查日期跨度,时间跨度越小,距离现实日期越近,则分析结果更接近当前身体状况
-                  </p>
-                </div>
-              </template>
-            </el-tooltip>
-            <span
-              >系统分析数据检查日期范围:{{ detail.startTime }} 至
-              {{ detail.endTime }}</span
-            >
-          </div>
-          <div v-else></div>
-          <div>
-            <el-popconfirm title="是否确认重新分析?" @confirm="reAnalysis">
-              <template #reference>
-                <el-button type="primary" plain>
-                  <Refresh class="w-4 h-4" />
-                  <span>重新分析</span>
-                </el-button>
-              </template>
-            </el-popconfirm>
-          </div>
-        </div>
-        <LatestUserDataAnalysis v-if="resultRawJson" />
-        <el-empty v-else description="用户年龄小于18岁或暂无医疗检查数据无法分析数据"></el-empty>
-      </el-tab-pane>
-      <el-tab-pane label="风险变化趋势" lazy>
-        <TrendOfRiskChange />
-      </el-tab-pane>
-    </el-tabs>
-  </div>
-</template>
-<script setup>
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  reactive,
-  onMounted,
-  provide,
-  defineAsyncComponent
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import {
-  formatAge,
-  parseJsonData,
-  request,
-  transformDataExpand
-} from "@/utils";
-import { QuestionFilled, ArrowUp, Refresh } from "@element-plus/icons-vue";
-import { ElMessage } from "element-plus";
-
-const LatestUserDataAnalysis = defineAsyncComponent(() =>
-  import("./LatestUserDataAnalysis.vue")
-);
-const TrendOfRiskChange = defineAsyncComponent(() =>
-  import("./TrendOfRiskChange.vue")
-);
-
-const route = useRoute();
-const router = useRouter();
-
-const resultRawJson = ref();
-provide("resultRawJson", resultRawJson);
-const detail = ref({
-  startTime: "",
-  resultRawJson: "",
-  endTime: ""
-});
-const getReportDetail = async () => {
-  const { data } = await request.get(
-    "/idcService/mechanism/archivesReport/detail",
-    {
-      params: {
-        archivesId: route.query.archivesId
-      }
-    }
-  );
-  detail.value = data.detail;
-  resultRawJson.value = parseJsonData(data.detail.resultRawData);
-};
-getReportDetail();
-
-const reAnalysis = async () => {
-  const { data } = await request.post(
-    `/idcService/mechanism/archivesReport/reAnalysis`,
-    {
-      archivesId: route.query.archivesId
-    }
-  );
-  ElMessage.success("分析完成");
-  detail.value = data.detail;
-  resultRawJson.value = parseJsonData(data.detail.resultRawData);
-};
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 158
src/views/healthManagement/components/SetCheckItem.vue

@@ -1,158 +0,0 @@
-<template>
-  <div>
-    <div class="flex items-center mb-6">
-      设置检查项目:
-      <el-select
-        v-model="state.node"
-        placeholder="检查项目"
-        style="width: 115px"
-        filterable
-        @change="handleSearchrRelatedNode"
-      >
-        <el-option
-          v-for="item in state.nodeList"
-          :label="item.properties.name"
-          :value="item.id"
-          :key="item.id"
-        />
-      </el-select>
-      <el-select
-        v-model="state.related"
-        placeholder="请选择包含的检查项目"
-        style="width: 315px"
-        multiple
-        filterable
-      >
-        <el-option
-          v-for="item in state.relatedList"
-          :label="item.properties.name"
-          :value="item.properties.name"
-          :key="item.id"
-        />
-      </el-select>
-      <el-select
-        v-model="state.frequencyType"
-        placeholder="请选择检查周期/时间"
-      >
-        <el-option label="每天" :value="0"> </el-option>
-        <el-option label="每周" :value="1"> </el-option>
-        <el-option label="每月" :value="2"> </el-option>
-        <el-option :label="`指定时间后 ${props.date}`" :value="3"> </el-option>
-      </el-select>
-      <el-button type="primary" plain @click="handleAdd" class="ml-2"
-        >确认添加</el-button
-      >
-    </div>
-    <div>
-      <ComponentTableSetItem
-        :tableData="props.tableData"
-        :config="config"
-        @remove="handleRemove"
-        :date="props.date"
-      ></ComponentTableSetItem>
-    </div>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request } from "@/utils";
-import { ElMessage } from "element-plus";
-import { onMounted, reactive, defineProps } from "vue";
-import ComponentTableSetItem from "./TableSetItem.vue";
-
-const props = defineProps({
-  tableData: {
-    type: Array,
-    default: () => []
-  },
-  date: {
-    type: String,
-    default: ""
-  }
-});
-const emits = defineEmits(["add"]);
-const state = reactive({
-  node: "", // 检查项目
-  related: [],
-  nodeList: [],
-  relatedList: [],
-  frequencyType: 3
-  // tableData: []
-});
-const config = {
-  name: { label: "检查项目", prop: "name" },
-  content: { label: "包含的检查内容", prop: "content" },
-  duration: { label: "检查周期", prop: "duration", width: "420" },
-  timePreview: { label: "检查时间预览", prop: "timePreview" },
-  frequency: { label: "完成次数", prop: "frequency" },
-  remark: { label: "备注信息", prop: "remark" },
-  handle: { label: "操作", prop: "handle" }
-};
-const getNodeList = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 999,
-        tag: "医学检查项目"
-      }
-    })
-    .then(resp => {
-      state.nodeList = resp.data.list;
-    });
-};
-const handleAdd = () => {
-  if (!state.node || !state.related.length) {
-    return ElMessage.error("请选择检查项目");
-  }
-  let config = {
-    name: state.nodeList.find(v => v.id == state.node)?.properties.name,
-    content: state.related?.join("、"),
-    frequencyType: state.frequencyType,
-    duration: state.frequencyType == 3 ? props.date : "",
-    timePreview: "",
-    frequency: 1, // 完后次数
-    remark: "",
-    handle: "",
-    type: 0
-  };
-  console.log(props.tableData);
-
-  emits("add", config);
-
-  state.node = "";
-  state.related = [];
-};
-const handleRemove = index => {
-  props.tableData.splice(index, 1);
-};
-const handleSearchrRelatedNode = id => {
-  request
-    .get("/platformApi/graphService/open/node/related", {
-      params: {
-        id: id,
-        relationship: "可检测"
-      }
-    })
-    .then(resp => {
-      state.relatedList = resp.data;
-      state.related = [];
-    });
-};
-const onReset = () => {
-  state.node = "";
-  state.related = [];
-  getNodeList();
-};
-onMounted(onReset);
-
-//这里需要暴露出去不然父组件调用不到这个方法
-const getTableData = () => {
-  return {
-    name: "检查项目",
-    list: props.tableData
-  };
-};
-defineExpose({
-  getTableData,
-  onReset
-});
-</script>

+ 0 - 104
src/views/healthManagement/components/SetOtherItem.vue

@@ -1,104 +0,0 @@
-<template>
-  <div>
-    <div class="flex items-center mb-6">
-      设置其他事项:
-      <el-input
-        placeholder="请输入其他事项内容"
-        v-model="state.content"
-        clearable
-      ></el-input>
-      <el-select
-        v-model="state.frequencyType"
-        placeholder="请选择检查周期/时间"
-      >
-        <el-option label="每天" :value="0"> </el-option>
-        <el-option label="每周" :value="1"> </el-option>
-        <el-option label="每月" :value="2"> </el-option>
-        <el-option :label="`指定时间后 ${props.date}`" :value="3"> </el-option>
-      </el-select>
-      <el-button type="primary" plain @click="handleAdd" class="ml-2"
-        >确认添加</el-button
-      >
-    </div>
-    <div>
-      <ComponentTableSetItem
-        :tableData="props.tableData"
-        :config="config"
-        @remove="handleRemove"
-        :date="props.date"
-      ></ComponentTableSetItem>
-    </div>
-  </div>
-</template>
-<script lang="ts" setup>
-import { request } from "@/utils";
-import { ElMessage } from "element-plus";
-import { onMounted, reactive, defineProps } from "vue";
-import ComponentTableSetItem from "./TableSetItem.vue";
-
-const props = defineProps({
-  tableData: {
-    type: Array,
-    default: () => []
-  },
-  date: {
-    type: String,
-    default: ""
-  }
-});
-const emits = defineEmits(["add"]);
-const state = reactive({
-  content: "", // 检查项目
-  nodeList: [],
-  relatedList: [],
-  frequencyType: 3
-  // tableData: []
-});
-const config = {
-  content: { label: "事项内容", prop: "content" },
-  duration: { label: "完成周期", prop: "duration", width: "320" },
-  timePreview: { label: "完成时间预览", prop: "timePreview" },
-  frequency: { label: "完成次数", prop: "frequency" },
-  remark: { label: "备注信息", prop: "remark" },
-  handle: { label: "操作", prop: "handle" }
-};
-
-const handleAdd = () => {
-  if (!state.content) {
-    return ElMessage.error("请输入内容");
-  }
-  let config = {
-    content: state.content,
-    frequencyType: state.frequencyType,
-    duration: state.frequencyType == 3 ? props.date : state.frequencyType,
-    timePreview: "",
-    frequency: 1, // 完后次数
-    remark: "",
-    handle: "",
-    type: 1
-  };
-  console.log(props.tableData);
-
-  emits("add", config);
-
-  state.content = "";
-};
-const handleRemove = index => {
-  props.tableData.splice(index, 1);
-};
-const onReset = () => {
-  state.content = "";
-};
-
-//这里需要暴露出去不然父组件调用不到这个方法
-const getTableData = () => {
-  return {
-    name: "检查项目",
-    list: props.tableData
-  };
-};
-defineExpose({
-  getTableData,
-  onReset
-});
-</script>

+ 0 - 216
src/views/healthManagement/components/SetRetrun.vue

@@ -1,216 +0,0 @@
-<template>
-  <div>
-    <div class="flex items-center mb-6">
-      设置回访项目:
-      <el-select
-        v-model="curDiseaseId"
-        placeholder="请选择回访类型"
-        style="width: 115px"
-        filterable
-        clearable
-        @change="handleChangeIll"
-      >
-        <el-option
-          v-for="(item, index) in diseaseVisitList"
-          :key="index"
-          :label="item.properties?.name"
-          :value="item.id"
-        ></el-option>
-      </el-select>
-
-      <el-select
-        v-model="sn"
-        :disabled="!curDiseaseId"
-        placeholder="请选择回访类型"
-        filterable
-        clearable
-      >
-        <el-option
-          v-for="(item, index) in diseaseVisitFormList"
-          :key="index"
-          :label="item?.properties?.name"
-          :value="item?.properties?.name"
-        ></el-option>
-      </el-select>
-      <el-select
-        v-model="state.frequencyType"
-        placeholder="请选择检查周期/时间"
-      >
-        <el-option label="每天" :value="0"> </el-option>
-        <el-option label="每周" :value="1"> </el-option>
-        <el-option label="每月" :value="2"> </el-option>
-        <el-option :label="`指定时间后 ${props.date}`" :value="3"> </el-option>
-      </el-select>
-      <el-button type="primary" plain @click="handleAdd" class="ml-2"
-        >确认添加</el-button
-      >
-    </div>
-    <div>
-      <ComponentTableSetItem
-        :tableData="props.tableData"
-        :config="config"
-        @remove="handleRemove"
-        :date="props.date"
-      ></ComponentTableSetItem>
-    </div>
-  </div>
-</template>
-<script lang="ts" setup>
-import { computed, ref } from "vue";
-import { request } from "@/utils";
-import { ElMessage } from "element-plus";
-import { onMounted, reactive, defineProps } from "vue";
-import ComponentTableSetItem from "./TableSetItem.vue";
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-const useManageProject = useManageProjectStoreHook();
-
-const props = defineProps({
-  tableData: {
-    type: Array,
-    default: () => []
-  },
-  date: {
-    type: String,
-    default: ""
-  }
-});
-const emits = defineEmits(["add"]);
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-const state = reactive({
-  node: "", // 检查项目
-  related: "",
-  nodeList: [],
-  relatedList: [],
-  frequencyType: 3
-  // tableData: []
-});
-
-const curDiseaseId = ref();
-const sn = ref();
-const transferRawJson = ref();
-
-const config = {
-  name: { label: "回访类型", prop: "name" },
-  content: { label: "回访内容", prop: "content" },
-  duration: { label: "回访周期", prop: "duration", width: "420" },
-  timePreview: { label: "回访时间预览", prop: "timePreview" },
-  frequency: { label: "每次完成次数", prop: "frequency" },
-  remark: { label: "备注信息", prop: "remark" },
-  handle: { label: "操作", prop: "handle" }
-};
-
-const diseaseVisitList = ref([]);
-const diseaseVisitFormList = ref([]);
-const authForm = ref([]);
-const getDiseaseVisitData = async () => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 9999,
-      tag: "可回访"
-    }
-  });
-  const responseData = await request.get(
-    `/idcService/mechanism/formConfig/get`
-  );
-  diseaseVisitList.value = [];
-
-  if (responseData?.data?.list?.length) {
-    diseaseVisitList.value = [
-      {
-        id: "patrol",
-        properties: {
-          name: "巡访"
-        },
-        key: "patrol"
-      }
-    ];
-    authForm.value = responseData?.data?.list.map(v => {
-      return {
-        ...v,
-        id: v.formId,
-        properties: {
-          name: v.formTitle
-        }
-      };
-    });
-  }
-  diseaseVisitList.value.push(...data.list);
-  console.log("diseaseVisitList", diseaseVisitList.value);
-};
-const handleChangeIll = async id => {
-  if (id == "patrol") {
-    return (diseaseVisitFormList.value = authForm.value);
-  }
-  diseaseVisitFormList.value = await searchRelateNodes(id, "回访表单信息");
-};
-const searchRelateNodes = async (id, relationship) => {
-  if (!id) return;
-  const { data } = await request.get(`/graphService/open/node/related`, {
-    params: {
-      id,
-      relationship
-    }
-  });
-  return data;
-};
-const handleAdd = () => {
-  if (!curDiseaseId.value || !sn.value) {
-    return ElMessage.error("请选择回访疾病");
-  }
-  let config = {
-    name: diseaseVisitList.value.find(v => v.id == curDiseaseId.value)
-      ?.properties.name,
-    content: sn.value,
-    frequencyType: state.frequencyType,
-    duration: state.frequencyType == 3 ? props.date : "",
-    timePreview: "",
-    frequency: 1, // 完后次数
-    remark: "",
-    handle: "",
-    type: 2
-  };
-  console.log(props.tableData);
-
-  emits("add", config);
-
-  state.node = "";
-  state.related = "";
-};
-const handleRemove = index => {
-  props.tableData.splice(index, 1);
-};
-const handleSearchrRelatedNode = id => {
-  request
-    .get("/platformApi/graphService/open/node/related", {
-      params: {
-        id: id,
-        relationship: "可检测"
-      }
-    })
-    .then(resp => {
-      state.relatedList = resp.data;
-    });
-};
-const onReset = () => {
-  curDiseaseId.value = "";
-  sn.value = "";
-  getDiseaseVisitData();
-};
-onMounted(onReset);
-
-//这里需要暴露出去不然父组件调用不到这个方法
-const getTableData = () => {
-  return {
-    name: "检查项目",
-    list: props.tableData
-  };
-};
-defineExpose({
-  getTableData,
-  onReset
-});
-</script>

+ 0 - 685
src/views/healthManagement/components/SimpleQuestionItem.vue

@@ -1,685 +0,0 @@
-<template>
-  <div
-    class="question-content p-2 pl-4"
-    :class="{
-      'show-indicator': props.showIndicator,
-      'hide-survey-title': props.hideSurveyTitle
-    }"
-  >
-    <div>
-      <div class="text-base text-gray-800 mb-2">{{ item?.title }}</div>
-      <div class="text-gray-400 text-sm">{{ item?.remark }}</div>
-    </div>
-    <!-- 单选 -->
-    <template v-if="item.type === 'radio'">
-      <!-- 常规显示 -->
-      <div class="text-left padding-top-10 padding-bottom-10">
-        <el-radio-group v-model="item.value">
-          <div>
-            <div
-              v-for="(sub, idx) in item.choices"
-              :key="idx"
-              class="sub-title margin-top-5 hide"
-            >
-              <el-radio :label="idx">
-                <span
-                  class="cursor-copy"
-                  @click.stop="emitText(`&quot;${sub.label}&quot;`)"
-                  >{{ sub.label }}</span
-                >
-              </el-radio>
-              <!-- <el-tag type="info" class="cursor-copy" @click="emitText(sub.attr)">{{
-                sub.attr
-              }}</el-tag> -->
-              <div
-                v-if="idx == item.value && item.choices[idx]?.isInput"
-                class="text-sm pl-6"
-              >
-                <span class="text-xs text-gray-500">输入内容:</span>
-                <span>{{ item.choices[idx]?.extra }}</span>
-              </div>
-            </div>
-          </div>
-        </el-radio-group>
-      </div>
-    </template>
-    <!-- 多选 -->
-    <template v-else-if="item.type === 'checkbox'">
-      <!-- 常规显示 -->
-      <div class="text-left padding-top-10 padding-bottom-10">
-        <div
-          v-for="(sub, idx) in item.choices"
-          :key="idx"
-          class="sub-title margin-top-5"
-        >
-          <el-checkbox :checked="(item.value || []).includes(idx)">
-            <span
-              class="cursor-copy"
-              @click.stop="emitText(`&quot;${sub.label}&quot;`)"
-              >{{ sub.label }}</span
-            >
-          </el-checkbox>
-
-          <div
-            v-if="
-              (item.value || []).includes(idx) && item.choices[idx]?.isInput
-            "
-            class="text-sm pl-6"
-          >
-            <span class="text-xs text-gray-500">输入内容:</span>
-            <span>{{ item.choices[idx]?.extra }}</span>
-          </div>
-        </div>
-      </div>
-    </template>
-    <!-- 单行文本题 -->
-    <template v-else-if="item.type === 'input' || item.type === 'textarea'">
-      <!-- 常规显示 -->
-      <div class="text-left padding-top-10 padding-bottom-10">
-        <div>
-          <el-input
-            v-model="item.value"
-            :type="item.type === 'textarea' ? 'textarea' : 'text'"
-            :rows="3"
-          />
-        </div>
-      </div>
-    </template>
-    <!-- 量表题 -->
-    <template v-else-if="item.type === 'scale'">
-      <!-- 常规显示 -->
-      <div class="text-left padding-top-10 padding-bottom-10">
-        <div class="row pt-4">
-          <div class="flex">
-            <div class="flex items-center flex-col">
-              <span class="whitespace-nowrap mx-4">{{
-                item.choices[0].label
-              }}</span>
-              <div>{{ item.min }}</div>
-            </div>
-            <el-slider
-              v-model="item.value"
-              :show-tooltip="true"
-              :min="item.min"
-              :max="item.max"
-              :step="1"
-            />
-            <div class="flex items-center flex-col">
-              <span class="whitespace-nowrap mx-4">{{
-                item.choices[1].label
-              }}</span>
-              <div>{{ item.max }}</div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </template>
-    <template v-else-if="item.type === 'rating_scale'">
-      <!-- 常规显示 -->
-      <div class="text-left padding-top-10 padding-bottom-10">
-        <div class="row">
-          <span class="mr-4">{{ item.choices[0].label }}</span>
-          <el-radio-group>
-            <el-radio-button
-              :value="false"
-              v-for="(sub, idx) in item.max"
-              :key="idx"
-              >{{ idx + item.min }}</el-radio-button
-            >
-          </el-radio-group>
-          <span class="ml-2">{{ item.choices[1].label }}</span>
-        </div>
-      </div>
-    </template>
-    <!-- 评分题 -->
-    <template v-else-if="item.type === 'rating'">
-      <!-- 常规显示 -->
-      <div class="text-left py-2">
-        <div v-for="(sub, idx) in item.choices" :key="idx" class="mt-1">
-          <template v-if="item.isMultiple">
-            <el-checkbox :value="false"
-              >{{ sub.label }}({{ sub.score }})</el-checkbox
-            >
-          </template>
-          <template v-else>
-            <el-radio :value="false">{{ sub.label }}({{ sub.score }})</el-radio>
-          </template>
-        </div>
-      </div>
-    </template>
-    <!-- 文本描述 -->
-    <div class="pt-4 pb-8" v-else-if="item.type === 'text'">
-      <el-input
-        class="input"
-        v-model="item.title"
-        v-if="edit || item.edit"
-        placeholder="请输入文本"
-      />
-      <p v-else class="text-center">
-        <span @click.stop="emitText(`&quot;${item.title}&quot;`)"
-          >{{ item.title
-          }}<el-tag v-if="item.isRepeat" type="danger" size="mini"
-            >可多答</el-tag
-          ></span
-        >
-      </p>
-    </div>
-    <!-- 时间选择题 -->
-    <template v-else-if="item.type === 'date'">
-      <!-- 常规显示 -->
-      <div class="text-left padding-top-10 padding-bottom-10">
-        <div class="row">
-          <el-date-picker
-            v-model="item.value"
-            type="date"
-            :placeholder="item.remark || '选择时间'"
-          />
-        </div>
-      </div>
-    </template>
-    <!-- 矩阵题 -->
-    <template v-else-if="item.type === 'matrix_checkbox'">
-      <!-- 常规显示 -->
-      <div class="text-left py-2">
-        <div class="row">
-          <el-table :data="item.matrix">
-            <el-table-column>
-              <template #default="{ $index }">
-                <div class="survey-sub-title">
-                  {{ item.rows[$index]?.label }}
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column
-              v-for="(col, colIdx) in item.columns"
-              :key="colIdx"
-              :label="col.label"
-              align="center"
-            >
-              <template #header="{ $index }">
-                {{ col.label }}
-              </template>
-              <template #default="{ $index }">
-                <el-checkbox
-                  readonly
-                  :checked="
-                    (item.value || []).includes(
-                      `${item.rows[$index]?.label}${item.columns[colIdx]?.label}`
-                    )
-                  "
-                />
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-      </div>
-    </template>
-    <!-- 疾病下拉题 -->
-    <template v-else-if="item.type === 'disease' || item.type === 'medicine'">
-      <!-- 常规显示 -->
-      <div class="text-left py-2">
-        <div class="row">
-          <p>推荐展示值</p>
-          <div
-            v-for="(recommend, recommendIndex) in item.cacheSearchList"
-            :key="recommendIndex"
-          >
-            {{ recommend.name }}({{ recommend.sn }})
-          </div>
-        </div>
-      </div>
-    </template>
-    <!-- 下拉题 -->
-    <template v-else-if="item.type === 'select'">
-      <!-- 常规显示 -->
-      <div class="text-left py-2">
-        <div class="row">
-          <p>推荐展示值</p>
-          <div
-            v-for="(recommend, recommendIndex) in item.cacheSearchList"
-            :key="recommendIndex"
-          >
-            {{ recommend.name }}({{ recommend.sn }})
-          </div>
-        </div>
-      </div>
-    </template>
-    <!-- 组合题 -->
-    <template v-else-if="item.type === 'group'">
-      <!-- 常规显示 -->
-      <div class="text-left py-2">
-        <div
-          v-for="(sub, subIdx) in item.children"
-          :key="subIdx"
-          class="template-question-child"
-        >
-          <TempQuestionItem
-            v-model:info="item.children[subIdx]"
-            :indicator="item.belongIndicator"
-            :show-indicator="true"
-            :edit="item.edit"
-            :is-child="true"
-            :target-prefix="targetPrefix"
-            @text="emitText"
-          />
-        </div>
-      </div>
-    </template>
-    <template v-else-if="item.type === 'combination'">
-      <!-- 常规显示 -->
-      <div class="text-left py-2">
-        <div v-for="(sub, subIdx) in item.children" :key="subIdx">
-          <TempQuestionItem
-            v-model:info="item.children[subIdx]"
-            :indicator="item.belongIndicator"
-            :show-indicator="true"
-            :edit="item.edit"
-            :target-prefix="targetPrefix"
-            @text="emitText"
-          />
-        </div>
-      </div>
-    </template>
-    <template v-else-if="item.type === 'upload'">
-      <template />
-    </template>
-    <ComponentRegex
-      v-model:visible="state.regexVisible"
-      ref="regexRef"
-      @success="onRegexSave"
-    />
-  </div>
-</template>
-<script setup>
-import { defineOptions, onMounted, computed, reactive, ref } from "vue";
-import { randomString, request } from "@/utils";
-import {
-  simpleTypes,
-  typeLabelByKey as typeLabel
-} from "@/enumerated/questionEnum";
-
-import { copyTextToClipboard } from "@pureadmin/utils";
-import { Rank, Close, CircleClose } from "@element-plus/icons-vue";
-import ComponentRegex from "@/components/Question/Regex.vue";
-const QUESTION_TYPE_TEMP_CHECK = "temp_check";
-const QUESTION_TYPE_ANSWER = "answer";
-const QUESTION_TYPE_INPUT = "input";
-const QUESTION_TYPE_TEXT = "text";
-const QUESTION_TYPE_CHECKBOX = "checkbox";
-const QUESTION_TYPE_RADIO = "radio";
-const QUESTION_TYPE_SELECT = "select";
-const QUESTION_TYPE_RATING_SCALE = "rating_scale";
-const QUESTION_TYPE_RATING = "rating";
-const QUESTION_TYPE_DATE = "date";
-const QUESTION_TYPE_UPLOAD = "upload";
-const QUESTION_TYPE_MATRIX = "matrix_checkbox";
-const QUESTION_TYPE_COMBINATION = "combination";
-const QUESTION_TYPE_GROUP = "group"; // 组合题
-defineOptions({
-  name: "TempQuestionItem"
-});
-const props = defineProps([
-  "info",
-  "id",
-  "edit",
-  "showIndicator",
-  "isChild",
-  "hideSurveyTitle",
-  "indicator",
-  "targetPrefix"
-]);
-const emits = defineEmits(["update:info", "text"]);
-const item = computed({
-  get() {
-    const info = props.info;
-    if (props.showIndicator && props.indicator) {
-      info.number = `${props.indicator.var}["${info.attr}"]`;
-    } else if (props.showIndicator && info.belongIndicator) {
-      info.number = `${info.belongIndicator.var}["${info.attr}"]`;
-    }
-    return info;
-  },
-  set(v) {
-    emits("update:info", v);
-  }
-});
-
-const state = reactive({
-  regexVisible: false,
-  isParentRegex: false,
-  subIndex: -1,
-  childType: "",
-  tags: []
-});
-const getTags = async (params = {}) => {
-  // const { data } = await request.get("/mechanism/systemTag/list", { params });
-  // state.tags = data.list;
-  // return data.list;
-  return [];
-};
-const searchChange = () => {
-  item.value.cacheSearchList = item.value.recommend
-    .map(id => {
-      return item.value.searchList.find(v => v.id == id);
-    })
-    .filter(v => v);
-};
-const searchDiseaseOrMedicine = (key = "") => {
-  const urls = {
-    disease: "/api/disease/list",
-    medicine: "/api/medicine/list"
-  };
-  const url = urls[props.info.type];
-  url &&
-    request
-      .get(url, {
-        params: { key }
-      })
-      .then(({ data }) => {
-        item.value.searchList = data.list;
-      });
-};
-const regexRef = ref();
-const setRegex = (subItem, subIndex, flag = false) => {
-  console.log(regexRef.value);
-  regexRef.value.setTpl(subItem.regexRule);
-  if (!flag) {
-    state.subIdx = subIndex;
-  }
-  state.regexVisible = true;
-  state.isParentRegex = flag;
-};
-const onRegexSave = data => {
-  console.log(data);
-  console.log(state.isParentRegex);
-  if (state.isParentRegex) {
-    item.value.config.regexRuleName = data.name;
-    item.value.config.regexRule = data;
-  } else {
-    if (item.value.choices[state.subIdx]) {
-      item.value.choices[state.subIdx].regexRuleName = data.name;
-      item.value.choices[state.subIdx].regexRule = data;
-    }
-  }
-};
-const emitText = e => {
-  if (!e) return;
-  const rText = props.targetPrefix || "tar";
-  const str = e.replace(/target/, rText).replace(/\./, "");
-  console.log(rText, str);
-  copyTextToClipboard(str);
-  emits("text", str);
-};
-const addGroupChild = () => {
-  const line = {
-    type: state.childType,
-    edit: true,
-    title: "",
-    value: "",
-    attr: randomString(5),
-    sn: "",
-    remark: "",
-    combination: "",
-    isRepeat: false,
-    config: {
-      desc: "",
-      rule: "",
-      type: "",
-      regexRule: "",
-      regexRuleName: ""
-    },
-    choices: [],
-    children: []
-  };
-  switch (line.type) {
-    case "radio":
-      line.choices = [
-        {
-          label: "选项1",
-          isInput: false,
-          extra: "",
-          inputPlaceholder: "",
-          regexRule: "",
-          regexRuleName: "",
-          attr: randomString(6)
-        },
-        {
-          label: "选项2",
-          isInput: false,
-          extra: "",
-          inputPlaceholder: "",
-          regexRule: "",
-          regexRuleName: "",
-          attr: randomString(6)
-        }
-      ];
-      break;
-    case "checkbox":
-      line.choices = [
-        {
-          label: "选项1",
-          mutuallyExclusive: false,
-          isInput: false,
-          extra: "",
-          inputPlaceholder: "",
-          regexRule: "",
-          regexRuleName: "",
-          attr: randomString(6)
-        },
-        {
-          label: "选项2",
-          mutuallyExclusive: false,
-          isInput: false,
-          extra: "",
-          inputPlaceholder: "",
-          regexRule: "",
-          regexRuleName: "",
-          attr: randomString(6)
-        }
-      ];
-      line.isMultiple = true;
-      break;
-    case "rating_scale":
-      line.min = 1;
-      line.max = 5;
-      line.choices = [
-        {
-          label: "不满意"
-        },
-        {
-          label: "非常满意"
-        }
-      ];
-      break;
-    case "rating":
-      line.choices = [
-        {
-          label: "选项1",
-          score: 0
-        },
-        {
-          label: "选项2",
-          score: 0
-        }
-      ];
-      line.isMultiple = false;
-      break;
-    case "date":
-      break;
-    case "disease":
-    case "medicine":
-      line.config.isInput = false;
-      line.config.attr = "extra";
-      line.recommend = [];
-      line.searchList = [];
-      line.cacheSearchList = [];
-      line.systemTagIds = [];
-      break;
-    case "matrix_checkbox":
-      line.columns = [
-        {
-          label: "选项1",
-          mutuallyExclusive: false
-        },
-        {
-          label: "选项2",
-          mutuallyExclusive: false
-        }
-      ];
-      line.rows = [
-        {
-          label: "问题1"
-        },
-        {
-          label: "问题2"
-        }
-      ];
-      line.matrix = [];
-      line.isMultiple = false;
-      break;
-  }
-  item.value.children.push(line);
-};
-const updateMatrix = () => {
-  props.info.matrix = Array(props.info.rows.length)
-    .fill(0)
-    .map(() => Array(props.info.columns.length).fill(false));
-};
-
-const formatResultList = arr => {
-  const list = [];
-  const repeatKey = [];
-  arr.forEach(v => {
-    if (v.isRepeat) {
-      if (!repeatKey.includes(v.sn)) {
-        const temp = {
-          ...v,
-          value: []
-        };
-        repeatKey.push(v.sn);
-        const cur = arr.filter(v2 => v2.sn === v.sn);
-        console.log("cur", cur);
-
-        temp.value = cur.map(formatItemVal);
-
-        temp.rawValue = cur.map(v2 => {
-          if (v.type == QUESTION_TYPE_GROUP) {
-            return v2.children.map(v3 => v3.value);
-          } else {
-            return v2.value;
-          }
-        });
-        console.log(temp.value, temp.rawValue);
-        list.push(temp);
-      }
-    } else {
-      console.log(v.type == QUESTION_TYPE_GROUP && "出现组合题", v);
-      if (v.type == QUESTION_TYPE_GROUP) {
-        list.push({
-          ...v,
-          rawValue: v.children.map(child => child.value),
-          value: formatItemVal(v)
-        });
-      } else {
-        list.push({
-          ...v,
-          rawValue: v.value,
-          value: formatItemVal(v)
-        });
-      }
-    }
-  });
-  return list;
-};
-
-onMounted(() => {
-  if (
-    props.info &&
-    (!props.info.matrix ||
-      !props.info.matrix.length ||
-      props.info.matrix.flat().length !=
-        props.info.rows.length * props.info.columns.length) &&
-    props.info.type === "matrix_checkbox"
-  ) {
-    props.info.matrix = Array(props.info.rows.length)
-      .fill(0)
-      .map(() => Array(props.info.columns.length).fill(false));
-  } else if (props.info.type === "group") {
-    props.info.children.forEach(v => {
-      v.edit = props.info.edit;
-    });
-  }
-  if (props.edit || props.info.edit) {
-    searchDiseaseOrMedicine();
-    getTags();
-  }
-});
-</script>
-<style lang="scss">
-.q-attr {
-  cursor: copy;
-  user-select: none;
-  margin-left: 10px;
-}
-.cursor-copy {
-  cursor: copy;
-}
-.show-indicator {
-  .survey-title,
-  .sub-title {
-    &:before {
-      display: none;
-      //   cursor: copy;
-      //   display: inline-block;
-      //   margin-bottom: 6px;
-    }
-    span {
-      display: inline-block;
-      margin: 5px auto;
-    }
-    &.hide {
-      &:before {
-        display: none;
-      }
-    }
-  }
-  .survey-title {
-    // left: -60px;
-    cursor: copy;
-
-    &:before {
-      // font-size: 14px !important;
-      // padding: 6px 15px !important;
-      // left: 0 !important;
-      // top: -3em !important;
-      display: none;
-    }
-  }
-
-  .el-checkbox__input.is- + span.el-checkbox__label {
-    cursor: copy;
-  }
-}
-.template-question-child {
-  position: relative;
-  background: #f5f5f5;
-  border-radius: 4px;
-  margin-bottom: 10px;
-  padding-top: 10px;
-  .template-question-child-close {
-    position: absolute;
-    top: 10px;
-    right: 10px;
-    font-size: 24px;
-    color: #999;
-    cursor: pointer;
-  }
-}
-.hide-survey-title {
-  .survey-title {
-    &:before {
-      display: none;
-    }
-  }
-}
-</style>

+ 0 - 126
src/views/healthManagement/components/TableSetItem.vue

@@ -1,126 +0,0 @@
-<template>
-  <div>
-    <el-table :data="props.tableData" style="width: 100%">
-      <el-table-column
-        v-for="(item, index) in props.config"
-        :key="index"
-        :label="item?.label"
-        :width="item?.width"
-      >
-        <template #default="{ row, $index }">
-          <div v-if="item.prop == 'duration'" class="flex item-center">
-            <!-- <el-select v-model="row.frequencyType" placeholder="">
-              <el-option
-                v-for="item in timeTypeList"
-                :label="item.label"
-                :value="item.value"
-                :key="item.value"
-              >
-              </el-option>
-            </el-select> -->
-            <el-text>{{ timeTypeList[row.frequencyType]?.label }}</el-text>
-            <el-input
-              v-if="row.frequencyType !== 3"
-              v-model="row.duration"
-              clearable
-              :placeholder="placeholderList[row.frequencyType]"
-              class="ml-2"
-              style="width: 200px"
-            ></el-input>
-          </div>
-          <div v-else-if="item.prop == 'timePreview'">
-            <span v-if="row.frequencyType == 2">
-              <div v-for="(item, index) in getMonth(row.duration)" :key="index">
-                {{ item }}
-              </div>
-            </span>
-            <span v-else-if="row.frequencyType == 1 && row.duration">
-              {{ previewTime(row.frequencyType, row.duration)?.label }} 每周
-            </span>
-            <span v-else-if="row.frequencyType == 3">{{ row.duration }}</span>
-            <span v-else>{{
-              previewTime(row.frequencyType, row.duration)?.label
-            }}</span>
-          </div>
-          <!-- <div v-else-if="item.prop == 'frequency'">
-
-          </div> -->
-          <div v-else-if="item.prop == 'remark'">
-            <el-input
-              v-model="row.remark"
-              placeholder="(选填)请输入备注信息"
-            ></el-input>
-          </div>
-          <div v-else-if="item.prop == 'handle'">
-            <el-button type="primary" link @click="handleRemove($index)"
-              >移除</el-button
-            >
-          </div>
-          <div v-else>
-            {{ row[item.prop] }}
-          </div>
-        </template>
-      </el-table-column>
-    </el-table>
-  </div>
-</template>
-<script lang="ts" setup>
-import { previewTime } from "@/utils/index";
-import moment from "moment";
-
-const emits = defineEmits(["remove"]);
-const props = defineProps({
-  tableData: {
-    type: Array,
-    default: () => []
-  },
-  config: {
-    type: Object,
-    default: () => {}
-  }
-});
-const timeTypeList = [
-  {
-    label: "每天",
-    value: 0
-  },
-  {
-    label: "每周",
-    value: 1
-  },
-  {
-    label: "每月",
-    value: 2
-  },
-  {
-    label: "指定时间",
-    value: 3
-  }
-];
-const placeholderList = {
-  0: "请输入持续天数",
-  1: "请输入持续周数",
-  2: "请输入持续月数",
-  3: "请输入固定天数"
-};
-const handleRemove = index => {
-  console.log("删除的下标", index);
-  emits("remove");
-};
-const getMonth = count => {
-  console.log(count);
-
-  if (!count) return [];
-  let date = [];
-  for (let i = 0; i < count; i++) {
-    date.push(
-      moment()
-        .add(i + 1, "months")
-        .format("YYYY-MM-DD")
-    );
-  }
-  console.log("date", date);
-
-  return date;
-};
-</script>

+ 0 - 205
src/views/healthManagement/components/TodoItemCheck.vue

@@ -1,205 +0,0 @@
-<template>
-  <div>
-    <el-form
-      ref="formRef"
-      :model="form"
-      label-width="120px"
-      label-position="left"
-    >
-      <el-form-item
-        label="复查主题:"
-        :rules="[
-          {
-            required: true,
-            message: '请输入复查主题',
-            trigger: 'blur'
-          }
-        ]"
-      >
-        <el-input
-          v-model="form.theme"
-          class="w-96"
-          placeholder="请输入复查主题,如XX疾病定期复查"
-        />
-      </el-form-item>
-      <el-form-item label="复查时间:" required>
-        <TagsDatePicker v-model:list="dayList" placeholder="复查时间" />
-      </el-form-item>
-      <el-radio-group v-model="type">
-        <el-radio-button :label="1">复查项目</el-radio-button>
-        <el-radio-button :label="2">事项提醒备注</el-radio-button>
-      </el-radio-group>
-      <el-form-item label="" />
-      <template v-if="type === 1">
-        <el-form-item label="复查项目:" required>
-          <div class="flex w-full">
-            <el-select
-              v-model="form.hospitalId"
-              placeholder="请选择"
-              @change="getMedicalCheckItems"
-            >
-              <el-option
-                v-for="item in medicalCheckList"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
-            <el-select
-              v-model="form.projectIds"
-              class="w-3/4"
-              placeholder="请选择"
-              filterable
-              multiple
-            >
-              <el-option
-                v-for="item in medicalCheckItemsList"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
-
-            <el-button plain type="primary" @click="handleAdd">确定</el-button>
-            <el-button type="primary" :icon="Refresh" link @click="onRefresh"
-              >刷新</el-button
-            >
-          </div>
-        </el-form-item>
-
-        <el-table :data="tableList" style="width: 100%">
-          <el-table-column label="复查项目">
-            <template #default="{ row }">
-              {{ row.name }}
-            </template>
-          </el-table-column>
-          <el-table-column label="操作">
-            <template #default="{ _index }">
-              <el-button type="danger" link @click="handleRemove(_index)"
-                >移除</el-button
-              >
-            </template>
-          </el-table-column>
-        </el-table>
-      </template>
-      <template v-else>
-        <Editor
-          v-model="form.remark"
-          placeholder="(选填)输入事项提醒备注,设置后用户可见"
-        />
-      </template>
-    </el-form>
-  </div>
-</template>
-<script setup>
-import { ref, reactive, defineExpose } from "vue";
-import { Refresh } from "@element-plus/icons-vue";
-import TagsDatePicker from "@/components/TagsDatePicker.vue";
-import Editor from "@/components/Editor.vue";
-import { request, unique } from "@/utils";
-import { ElMessage } from "element-plus";
-
-const form = reactive({
-  theme: "",
-  date: "",
-  hospitalId: "",
-  projectIds: "",
-  remark: ""
-});
-const type = ref(1);
-const dayList = ref([]);
-const medicalCheckList = ref([]);
-const medicalCheckItemsList = ref([]);
-const tableList = ref([]);
-
-const onInitEditData = data => {
-  form.theme = data.theme;
-  dayList.value = data.dates?.split("、");
-  tableList.value = data.content;
-  form.remark = data.remark == "<p><br></p>" ? "" : data.remark;
-};
-const getMedicalCheckList = () => {
-  request
-    .get("dataService/schemeManage/medicalCheck/hospital/paginate", {
-      params: {
-        pageSize: 999
-      }
-    })
-    .then(resp => {
-      const data = resp.data.list;
-      if (resp.data.total && !form.hospitalId) {
-        form.hospitalId = data[0].id;
-        getMedicalCheckItems();
-      }
-      medicalCheckList.value = data;
-    });
-};
-const getMedicalCheckItems = () => {
-  request
-    .get("dataService/schemeManage/medicalCheck/item/paginate", {
-      params: {
-        hospitalId: form.hospitalId,
-        pageSize: 999
-      }
-    })
-    .then(resp => {
-      medicalCheckItemsList.value = resp.data.list;
-    });
-};
-const handleAdd = () => {
-  const list = medicalCheckItemsList.value.filter(v =>
-    form.projectIds.includes(v.id)
-  );
-  tableList.value = unique([...tableList.value, ...list], "id");
-  // 这是是为了日常监测定义的content一致
-  tableList.value.forEach(v => {
-    v.properties = {
-      name: v.name
-    };
-  });
-  form.projectIds = [];
-};
-
-const handleRemove = index => {
-  tableList.value.splice(index, 1);
-};
-const onSubmit = callback => {
-  if (!form.theme) {
-    return ElMessage.error("请输入复查主题");
-  }
-  if (!dayList.value.length) {
-    return ElMessage.error("复查时间不能为空");
-  }
-  if (!tableList.value.length) {
-    return ElMessage.error("复查项目不能为空");
-  }
-  const params = {
-    theme: form.theme,
-    frequencyType: 3,
-    dates: dayList.value.join("、"),
-    content: tableList.value,
-    remark: form.remark == "<p><br></p>" ? "" : form.remark
-  };
-  callback(params);
-};
-const onRefresh = () => {
-  getMedicalCheckList();
-  getMedicalCheckItems();
-};
-const onReset = () => {
-  form.theme = "";
-  dayList.value = [];
-  tableList.value = [];
-  form.remark = "";
-};
-const initData = () => {
-  getMedicalCheckList();
-};
-initData();
-defineExpose({
-  onSubmit,
-  onReset,
-  onInitEditData
-});
-</script>
-<style lang="scss " scoped></style>

+ 0 - 298
src/views/healthManagement/components/TodoItemFollowUp.vue

@@ -1,298 +0,0 @@
-<template>
-  <div>
-    <el-form
-      ref="formRef"
-      :model="form"
-      label-width="120px"
-      label-position="left"
-    >
-      <el-form-item
-        label="随访主题:"
-        :rules="[
-          {
-            required: true,
-            message: '请输入随访主题',
-            trigger: 'blur'
-          }
-        ]"
-      >
-        <el-input
-          v-model="form.theme"
-          class="w-96"
-          placeholder="请输入随访主题,如高血压回访"
-        />
-      </el-form-item>
-      <el-form-item label="随访日期:" required>
-        <TagsDatePicker v-model:list="dayList" placeholder="随访日期" />
-      </el-form-item>
-    </el-form>
-
-    <div class="flex-1 p-4 overflow-y-auto">
-      <div class="flex items-center">
-        <div class="flex-1">
-          <div
-            class="flex items-center w-fit border rounded-3xl border-solid border-gray-400 overflow-hidden"
-          >
-            <div
-              v-for="(item, index) in [
-                '随访问卷',
-                '随访健康指导',
-                '随访人员指导',
-                '事项提醒备注'
-              ]"
-              :key="index"
-              @click="curTab = index"
-              class="relative after:absolute after:right-0 after:top-2.5 after:w-[1px] after:h-4 after:bg-gray-400 after:content-[''] text-xs"
-            >
-              <div
-                class="cursor-pointer text-sm py-2 px-3 hover:bg-gray-100 first-of-type:pl-6 last-of-type:pr-6 flex items-center"
-                :class="{
-                  'bg-blue-500 hover:bg-blue-500 text-white': curTab == index
-                }"
-              >
-                {{ item }}
-              </div>
-            </div>
-          </div>
-        </div>
-        <div>
-          <el-button
-            v-if="!curTab && content?.questions?.length"
-            type="primary"
-            size="small"
-            @click="editContentVisible.questions = true"
-            >修改问卷</el-button
-          >
-          <el-button
-            v-if="curTab == 1 && content?.healthGuidance"
-            type="primary"
-            size="small"
-            @click="editContentVisible.healthGuidance = true"
-            >修改随访健康指导</el-button
-          >
-          <el-button
-            v-if="curTab == 2 && content?.visitGuidance"
-            type="primary"
-            size="small"
-            @click="editContentVisible.visitGuidance = true"
-            >修改随访人员指导</el-button
-          >
-        </div>
-
-        <div>
-          <el-button
-            type="primary"
-            link
-            :icon="FolderOpened"
-            class="ml-2"
-            @click="visiblePageReviewTemplate = true"
-            >在随访模版库中选择</el-button
-          >
-        </div>
-      </div>
-      <div v-if="curTab == 0" class="pt-6">
-        <div v-if="content?.questions?.length">
-          <div
-            v-for="(item, index) in content?.questions"
-            :key="index"
-            class="m-1 bg-gray-100 rounded p-4 mb-3"
-          >
-            <SimpleQuestionItem :info="item" :id="item.id" :edit="false" />
-          </div>
-        </div>
-        <div
-          class="flex flex-col items-center px-4 py-6 mx-[14%] mt-[10%] rounded-lg bg-gray-100 space-y-4"
-          v-else
-        >
-          <div>
-            创建随访问卷,可对用户情况进行标准化信息回收,方便后期对比查看管理效果
-          </div>
-          <el-button type="primary" @click="editContentVisible.questions = true"
-            >立即创建</el-button
-          >
-        </div>
-      </div>
-      <div v-else-if="curTab == 1" class="py-4 px-2">
-        <div v-if="content?.healthGuidance" v-html="content?.healthGuidance" />
-        <div
-          v-else
-          class="flex flex-col items-center px-4 py-6 mx-[14%] mt-[10%] rounded-lg bg-gray-100 space-y-4"
-        >
-          <div>
-            设置健康指导内容,方便用户了解在不同时期如何进行自我管理,以及健康注意事项
-          </div>
-          <el-button
-            type="primary"
-            @click="editContentVisible.healthGuidance = true"
-            >立即创建</el-button
-          >
-        </div>
-      </div>
-      <div v-else-if="curTab == 2" class="py-4 px-2">
-        <div v-if="content?.visitGuidance" v-html="content?.visitGuidance" />
-        <div
-          v-else
-          class="flex flex-col items-center px-4 py-6 mx-[14%] mt-[10%] rounded-lg bg-gray-100 space-y-4"
-        >
-          <div>设置随访人员指导内容,指导随访人员如何进行随访</div>
-          <el-button
-            type="primary"
-            @click="editContentVisible.visitGuidance = true"
-            >立即创建</el-button
-          >
-        </div>
-      </div>
-      <div v-else>
-        <Editor
-          class="mt-4"
-          v-model:value="form.remark"
-          placeholder="请输入事项提醒备注"
-        />
-      </div>
-    </div>
-
-    <el-drawer v-model="visiblePageReviewTemplate" direction="rtl" size="70%">
-      <div>
-        <PageReviewTemplate @onSelect="handleCurrentTemplate" />
-      </div>
-    </el-drawer>
-
-    <DialogEditQuestion
-      v-model:show="editContentVisible.questions"
-      :initQuestions="content?.questions"
-      :initRules="content?.logicCode"
-      :submit-questions="saveQuestions"
-      :submit-logic="saveLogicCode"
-    />
-    <el-dialog
-      append-to-body
-      v-model="editContentVisible.healthGuidance"
-      title="随访健康指导"
-    >
-      <Editor v-model:value="content.healthGuidance" />
-      <template #footer>
-        <el-button type="primary" @click="saveCurValue('healthGuidance')"
-          >保存</el-button
-        >
-      </template>
-    </el-dialog>
-    <el-dialog
-      append-to-body
-      v-model="editContentVisible.visitGuidance"
-      title="随访人员指导"
-    >
-      <Editor v-model:value="content.visitGuidance" />
-      <template #footer>
-        <el-button type="primary" @click="saveCurValue('visitGuidance')"
-          >保存</el-button
-        >
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import { ref, reactive, defineExpose } from "vue";
-import { FolderOpened } from "@element-plus/icons-vue";
-
-import DialogEditQuestion from "@/components/Survey/DialogEditQuestion.vue";
-import TagsDatePicker from "@/components/TagsDatePicker.vue";
-import Editor from "@/components/Editor.vue";
-import SimpleQuestionItem from "@/components/Survey/SimpleQuestionItem.vue";
-import PageReviewTemplate from "@/views/schemeLibrary/reviewTemplate.vue";
-
-import { ElMessage } from "element-plus";
-
-const form = reactive({
-  theme: "",
-  remark: ""
-});
-const content = reactive({
-  healthGuidance: "",
-  visitGuidance: "",
-  questions: [],
-  logicCode: [] // 问卷逻辑规则设置
-});
-const visiblePageReviewTemplate = ref(false);
-const formRef = ref();
-const dayList = ref([]);
-const curTab = ref(0);
-
-const editContentVisible = reactive({
-  questions: false,
-  healthGuidance: false,
-  visitGuidance: false
-});
-
-const saveQuestions = async questions => {
-  content.questions = questions;
-  // ElMessage.success("保存成功");
-  saveCurValue("questions");
-};
-const saveLogicCode = async rules => {
-  content.logicCode = rules;
-  saveCurValue("logicCode");
-};
-const saveCurValue = async prop => {
-  editContentVisible[prop] = false;
-};
-const handleCurrentTemplate = template => {
-  content.logicCode = template?.logicCode;
-  content.questions = template?.questions;
-  content.healthGuidance = template?.healthGuidance;
-  content.visitGuidance = template?.visitGuidance;
-  visiblePageReviewTemplate.value = false;
-};
-const onSubmit = callback => {
-  if (!form.theme) {
-    return ElMessage.error("请输入随访主题");
-  }
-  if (!dayList.value.length) {
-    return ElMessage.error("随访日期间不能为空");
-  }
-  const params = {
-    ...form,
-    dates: dayList.value.join("、"),
-    remark: form.remark == "<p><br></p>" ? "" : form.remark,
-    frequencyType: 3,
-    content: {
-      ...content,
-      healthGuidance:
-        content.healthGuidance == "<p><br></p>" ? "" : content.healthGuidance,
-      visitGuidance:
-        content.visitGuidance == "<p><br></p>" ? "" : content.visitGuidance
-    }
-  };
-  callback(params);
-};
-const onReset = () => {
-  dayList.value = [];
-  form.remark = "";
-  curTab.value = 0;
-  content.questions = [];
-  content.healthGuidance = "";
-  content.visitGuidance = "";
-  formRef.value?.resetFields();
-};
-const onInitEditData = data => {
-  onReset();
-  form.theme = data.theme;
-  dayList.value = data.dates?.split("、");
-  form.remark = data.remark == "<p><br></p>" ? "" : data.remark;
-  content.healthGuidance =
-    data?.content.healthGuidance == "<p><br></p>"
-      ? ""
-      : data?.content.healthGuidance;
-  content.visitGuidance =
-    data?.content.visitGuidance == "<p><br></p>"
-      ? ""
-      : data?.content.visitGuidance;
-  content.questions = data.content?.questions || [];
-  content.logicCode = data.content?.logicCode || [];
-};
-defineExpose({
-  onSubmit,
-  onReset,
-  onInitEditData
-});
-</script>
-<style lang="scss " scoped></style>

+ 0 - 180
src/views/healthManagement/components/TodoItemInspect.vue

@@ -1,180 +0,0 @@
-<template>
-  <div>
-    <el-form
-      ref="formRef"
-      :model="form"
-      label-width="120px"
-      label-position="left"
-    >
-      <el-form-item
-        label="事项主题:"
-        :rules="[
-          {
-            required: true,
-            message: '请输入事项主题',
-            trigger: 'blur'
-          }
-        ]"
-      >
-        <el-input
-          v-model="form.name"
-          class="w-96"
-          placeholder="请输入事项主题"
-        />
-      </el-form-item>
-      <el-form-item label="检查事项:" required>
-        <el-select
-          v-model="form.node"
-          placeholder="检查项目"
-          style="width: 115px"
-          filterable
-          @change="handleSearchrRelatedNode"
-        >
-          <el-option
-            v-for="item in state.nodeList"
-            :label="item.properties.name"
-            :value="item.id"
-            :key="item.id"
-          />
-        </el-select>
-        <el-select
-          v-model="form.related"
-          placeholder="请选择包含的检查项目"
-          style="width: 315px"
-          multiple
-          filterable
-        >
-          <el-option
-            v-for="item in state.relatedList"
-            :label="item.properties.name"
-            :value="item.properties.name"
-            :key="item.id"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="待办日期:" required>
-        <el-space wrap>
-          <el-select
-            v-model="form.frequencyType"
-            placeholder="请选择检查周期/时间"
-          >
-            <el-option label="指定日期" :value="3" />
-            <el-option label="每天" :value="0" />
-            <el-option label="每周" :value="1" />
-            <el-option label="每月" :value="2" />
-          </el-select>
-          <template v-if="form.frequencyType < 3">
-            <!-- <el-date-picker
-              value-format="YYYY-MM-DD"
-              v-model="time"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-            /> -->
-          </template>
-          <template v-else>
-            <TagsDatePicker v-model:list="dayList" placeholder="请选择日期" />
-          </template>
-          <el-button type="primary" plain @click="handleAdd" class="ml-2"
-            >确认添加</el-button
-          >
-        </el-space>
-      </el-form-item>
-    </el-form>
-    <div>
-      <ComponentTableSetItem
-        :tableData="state.tableData"
-        :config="config"
-        @remove="handleRemove"
-        date="2020-09-01"
-      />
-    </div>
-  </div>
-</template>
-<script setup>
-import { ref, reactive } from "vue";
-import { request } from "@/utils";
-
-import TagsDatePicker from "@/components/TagsDatePicker.vue";
-import { ElMessage } from "element-plus";
-import ComponentTableSetItem from "./TableSetItem.vue";
-
-const form = reactive({
-  name: "",
-  node: "", // 检查项目
-  related: "",
-  date: "",
-  frequencyType: 3
-});
-
-const config = {
-  name: { label: "检查项目", prop: "name" },
-  content: { label: "包含的检查内容", prop: "content" },
-  duration: { label: "检查周期", prop: "duration", width: "420" },
-  timePreview: { label: "检查时间预览", prop: "timePreview" },
-  frequency: { label: "完成次数", prop: "frequency" },
-  remark: { label: "备注信息", prop: "remark" },
-  handle: { label: "操作", prop: "handle" }
-};
-const time = ref([]);
-const dayList = ref([]);
-const state = reactive({
-  nodeList: [],
-  relatedList: [],
-  frequencyType: 3,
-  tableData: []
-  // tableData: []
-});
-
-const handleSearchrRelatedNode = id => {
-  request
-    .get("/platformApi/graphService/open/node/related", {
-      params: {
-        id: id,
-        relationship: "可检测"
-      }
-    })
-    .then(resp => {
-      state.relatedList = resp.data;
-      form.related = [];
-    });
-};
-const handleAdd = () => {
-  if (!form.node || !form.related.length) {
-    return ElMessage.error("请选择检查项目");
-  }
-  const config = {
-    name: state.nodeList.find(v => v.id == form.node)?.properties.name,
-    content: form.related?.join("、"),
-    frequencyType: state.frequencyType,
-    duration: state.frequencyType == 3 ? dayList.value.join(",") : "",
-    timePreview: "",
-    frequency: 1, // 完后次数
-    remark: "",
-    handle: "",
-    type: 0
-  };
-  state.tableData.push(config);
-  form.node = "";
-  form.related = [];
-  dayList.value = [];
-};
-
-const handleRemove = index => {
-  state.tableData.splice(index, 1);
-};
-const getNodeList = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 999,
-        tag: "医学检查项目"
-      }
-    })
-    .then(resp => {
-      state.nodeList = resp.data.list;
-    });
-};
-getNodeList();
-</script>
-<style lang="scss " scoped></style>

+ 0 - 197
src/views/healthManagement/components/TodoItemMonitor.vue

@@ -1,197 +0,0 @@
-<template>
-  <div>
-    <el-form
-      ref="formRef"
-      :model="form"
-      label-width="120px"
-      label-position="left"
-    >
-      <el-form-item
-        label="监测主题:"
-        :rules="[
-          {
-            required: true,
-            message: '请输入监测主题',
-            trigger: 'blur'
-          }
-        ]"
-      >
-        <el-input
-          v-model="form.theme"
-          class="w-96"
-          placeholder="请输入监测主题,如血压日常监测"
-        />
-      </el-form-item>
-      <el-form-item label="监测周期:" required>
-        <el-space wrap>
-          <el-select
-            v-model="form.frequencyType"
-            placeholder="请选择检查周期/时间"
-            :disabled="props.isEdit"
-          >
-            <el-option label="每天" :value="0" />
-            <el-option label="每周" :value="1" />
-            <el-option label="每月" :value="2" />
-          </el-select>
-          <el-date-picker
-            value-format="YYYY-MM-DD"
-            v-model="form.date"
-            type="daterange"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            @change="handleChangeDate"
-          />
-        </el-space>
-      </el-form-item>
-      <el-radio-group v-model="type">
-        <el-radio-button :label="1">监测项目</el-radio-button>
-        <el-radio-button :label="2">事项提醒备注</el-radio-button>
-      </el-radio-group>
-      <el-form-item label="" />
-      <template v-if="type === 1">
-        <el-form-item label="监测项目:" required>
-          <div class="flex w-full">
-            <el-select
-              v-model="form.currentMonitors"
-              placeholder="请选择"
-              class="w-3/4"
-              multiple
-              filterable
-            >
-              <el-option
-                v-for="item in monitorItems"
-                :key="item.id"
-                :label="item.properties.name"
-                :value="item.id"
-              />
-            </el-select>
-            <el-button type="primary" plain @click="handleAdd">确定</el-button>
-            <el-button
-              type="primary"
-              :icon="Refresh"
-              link
-              @click="getMonitorItems"
-              >刷新</el-button
-            >
-          </div>
-        </el-form-item>
-        <el-table :data="tableList" style="width: 100%">
-          <el-table-column label="监测项目">
-            <template #default="{ row }">
-              {{ row.properties.name }}
-            </template>
-          </el-table-column>
-          <el-table-column label="操作">
-            <template #default="{ _index }">
-              <el-button type="danger" link @click="handleRemove(_index)"
-                >移除</el-button
-              >
-            </template>
-          </el-table-column>
-        </el-table>
-      </template>
-      <template v-else>
-        <Editor
-          v-model:value="form.remark"
-          placeholder="(选填)输入事项提醒备注,设置后用户可见"
-      /></template>
-    </el-form>
-  </div>
-</template>
-<script setup>
-import { ref, reactive, defineExpose, defineProps } from "vue";
-import { Refresh } from "@element-plus/icons-vue";
-import { request, unique } from "@/utils";
-import Editor from "@/components/Editor.vue";
-import { ElMessage } from "element-plus";
-const props = defineProps({
-  isEdit: {
-    type: Boolean,
-    default: false
-  }
-});
-const form = reactive({
-  theme: "",
-  date: [],
-  frequencyType: 0,
-  currentMonitors: [],
-  remark: ""
-});
-const formRef = ref();
-const type = ref(1);
-const dayList = ref([]);
-const monitorItems = ref([]);
-const tableList = ref([]);
-const handleChangeDate = value => {
-  if (!value) return;
-  if (dayList.value.includes(value)) return;
-  dayList.value.push(value);
-};
-const handleAdd = () => {
-  const list = monitorItems.value.filter(v =>
-    form.currentMonitors.includes(v.id)
-  );
-  tableList.value = unique([...tableList.value, ...list], "id");
-  form.currentMonitors = [];
-};
-const handleRemove = index => {
-  tableList.value.splice(index, 1);
-};
-const getMonitorItems = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 9999,
-        tag: "日常监测指标"
-      }
-    })
-    .then(resp => {
-      monitorItems.value = resp.data.list;
-    });
-};
-getMonitorItems();
-
-const onSubmit = callback => {
-  if (!form.theme) {
-    return ElMessage.error("请输入监测主题");
-  }
-  if (!form.date.length) {
-    return ElMessage.error("监测日期时间不能为空");
-  }
-  if (!tableList.value?.length) {
-    return ElMessage.error("监测项目不能为空");
-  }
-  const [startDate, endDate] = form.date;
-  const params = {
-    theme: form.theme,
-    frequencyType: form.frequencyType,
-    startDate,
-    endDate,
-    content: tableList.value,
-    remark: form.remark == "<p><br></p>" ? "" : form.remark
-  };
-  callback(params);
-};
-const onReset = () => {
-  form.currentMonitors = [];
-  form.date = [];
-  form.theme = "";
-  form.frequencyType = 0;
-  form.remark = "";
-  tableList.value = [];
-};
-const onInitEditData = data => {
-  onReset();
-  form.theme = data.theme;
-  form.frequencyType = data.frequencyType;
-  form.remark = data.remark == "<p><br></p>" ? "" : data.remark;
-  form.date = [data.startDate, data.endDate];
-  tableList.value = data.content || [];
-};
-defineExpose({
-  onSubmit,
-  onReset,
-  onInitEditData
-});
-</script>
-<style lang="scss " scoped></style>

+ 0 - 155
src/views/healthManagement/components/TodoItemOther.vue

@@ -1,155 +0,0 @@
-<template>
-  <div>
-    <el-form
-      ref="formRef"
-      :model="form"
-      label-width="120px"
-      label-position="left"
-    >
-      <el-form-item
-        label="事项主题:"
-        :rules="[
-          {
-            required: true,
-            message: '请输入事项主题',
-            trigger: 'blur'
-          }
-        ]"
-      >
-        <el-input
-          v-model="form.theme"
-          class="w-96"
-          placeholder="请输入事项主题"
-        />
-      </el-form-item>
-      <el-form-item label="待办日期:" required>
-        <el-space wrap>
-          <el-select
-            v-model="form.frequencyType"
-            placeholder="请选择检查周期/时间"
-            :disabled="props.isEdit"
-          >
-            <el-option label="指定日期" :value="3" />
-            <el-option label="每天" :value="0" />
-            <el-option label="每周" :value="1" />
-            <el-option label="每月" :value="2" />
-          </el-select>
-          <template v-if="form.frequencyType < 3">
-            <el-date-picker
-              value-format="YYYY-MM-DD"
-              v-model="time"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-            />
-          </template>
-          <template v-else>
-            <TagsDatePicker v-model:list="dayList" placeholder="请选择日期" />
-          </template>
-        </el-space>
-      </el-form-item>
-      <el-radio-group v-model="type">
-        <el-radio-button :label="1">事项内容</el-radio-button>
-        <el-radio-button :label="2">事项提醒备注</el-radio-button>
-      </el-radio-group>
-      <el-form-item label="" />
-      <template v-if="type === 1">
-        <el-input
-          type="textarea"
-          v-model="form.content"
-          :rows="24"
-          show-word-limit
-          placeholder="(必填)请输入事项内容"
-        />
-      </template>
-      <template v-else>
-        <Editor
-          v-model:value="form.remark"
-          placeholder="(选填)输入事项提醒备注,设置后用户可见"
-      /></template>
-    </el-form>
-  </div>
-</template>
-<script setup>
-import { ref, reactive, defineExpose, defineProps } from "vue";
-import Editor from "@/components/Editor.vue";
-import TagsDatePicker from "@/components/TagsDatePicker.vue";
-import { ElMessage } from "element-plus";
-const props = defineProps({
-  isEdit: {
-    type: Boolean,
-    default: false
-  }
-});
-const form = reactive({
-  theme: "",
-  date: "",
-  frequencyType: 3,
-  content: "",
-  remark: ""
-});
-const time = ref([]);
-const type = ref(1);
-const dayList = ref([]);
-
-const onSubmit = callback => {
-  if (!form.theme) {
-    return ElMessage.error("请输入事项主题");
-  }
-  let startDate = undefined;
-  let endDate = undefined;
-  if (!form.date.length && form.frequencyType < 3) {
-    return ElMessage.error("待办日期不能为空");
-  }
-
-  if (!dayList.value.length && form.frequencyType == 3) {
-    return ElMessage.error("待办日期不能为空");
-  }
-  if (!form.content) {
-    return ElMessage.error("请输入待办事项内容");
-  }
-  try {
-    [startDate, endDate] = form.date;
-  } catch (error) {
-    console.log(error);
-  }
-  const params = {
-    theme: form.theme,
-    frequencyType: form.frequencyType,
-    content: form.content,
-    remark: form.remark == "<p><br></p>" ? "" : form.remark
-  };
-  if (form.frequencyType == 3) {
-    params.dates = dayList.value.join("、");
-  } else {
-    params[startDate] = startDate;
-    params[endDate] = endDate;
-  }
-  callback(params);
-};
-const onReset = () => {
-  dayList.value = [];
-  form.date = [];
-  form.theme = "";
-  form.frequencyType = 3;
-  form.remark = "";
-  form.content = "";
-  // formRef.value.resetFields();
-};
-
-const onInitEditData = data => {
-  onReset();
-  form.theme = data.theme;
-  dayList.value = data.dates?.split("、");
-  form.remark = data.remark == "<p><br></p>" ? "" : data.remark;
-  form.content = data.content;
-  form.frequencyType = data.frequencyType;
-  form.date = [data.startDate, data.endDate];
-};
-defineExpose({
-  onSubmit,
-  onReset,
-  onInitEditData
-});
-</script>
-<style lang="scss " scoped></style>

+ 0 - 209
src/views/healthManagement/components/TodoItemReturnVisit.vue

@@ -1,209 +0,0 @@
-<template>
-  <div>
-    <el-form
-      ref="formRef"
-      :model="form"
-      label-width="120px"
-      label-position="left"
-    >
-      <el-form-item
-        label="事项主题:"
-        :rules="[
-          {
-            required: true,
-            message: '请输入事项主题',
-            trigger: 'blur'
-          }
-        ]"
-      >
-        <el-input
-          v-model="form.name"
-          class="w-96"
-          placeholder="请输入事项主题"
-        />
-      </el-form-item>
-      <el-form-item label="回访事项:" required>
-        <el-select
-          v-model="form.node"
-          placeholder="回访项目"
-          style="width: 115px"
-          filterable
-          @change="handleSearchrRelatedNode"
-        >
-          <el-option
-            v-for="item in state.nodeList"
-            :label="item.properties.name"
-            :value="item.id"
-            :key="item.id"
-          />
-        </el-select>
-        <el-select
-          v-model="form.related"
-          placeholder="请选择包含的回访项目"
-          style="width: 315px"
-          multiple
-          filterable
-        >
-          <el-option
-            v-for="item in state.relatedList"
-            :label="item.properties.name"
-            :value="item.properties.name"
-            :key="item.id"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="待办日期:" required>
-        <el-space wrap>
-          <el-select
-            v-model="form.frequencyType"
-            placeholder="请选择回访周期/时间"
-          >
-            <el-option label="指定日期" :value="3" />
-            <el-option label="每天" :value="0" />
-            <el-option label="每周" :value="1" />
-            <el-option label="每月" :value="2" />
-          </el-select>
-          <template v-if="form.frequencyType < 3">
-            <!-- <el-date-picker
-              value-format="YYYY-MM-DD"
-              v-model="time"
-              type="daterange"
-              start-placeholder="开始日期"
-              end-placeholder="结束日期"
-            /> -->
-          </template>
-          <template v-else>
-            <TagsDatePicker v-model:list="dayList" placeholder="请选择日期" />
-          </template>
-          <el-button type="primary" plain @click="handleAdd" class="ml-2"
-            >确认添加</el-button
-          >
-        </el-space>
-      </el-form-item>
-    </el-form>
-    <div>
-      <ComponentTableSetItem
-        :tableData="state.tableData"
-        :config="config"
-        @remove="handleRemove"
-        date="2020-09-01"
-      />
-    </div>
-  </div>
-</template>
-<script setup>
-import { ref, reactive } from "vue";
-import { request } from "@/utils";
-
-import TagsDatePicker from "@/components/TagsDatePicker.vue";
-import { ElMessage } from "element-plus";
-import ComponentTableSetItem from "./TableSetItem.vue";
-
-const form = reactive({
-  name: "",
-  node: "", // 回访项目
-  related: "",
-  date: "",
-  frequencyType: 3
-});
-
-const config = {
-  name: { label: "回访类型", prop: "name" },
-  content: { label: "回访内容", prop: "content" },
-  duration: { label: "回访周期", prop: "duration", width: "420" },
-  timePreview: { label: "回访时间预览", prop: "timePreview" },
-  frequency: { label: "每次完成次数", prop: "frequency" },
-  remark: { label: "备注信息", prop: "remark" },
-  handle: { label: "操作", prop: "handle" }
-};
-const dayList = ref([]);
-const authForm = ref([]);
-const state = reactive({
-  nodeList: [],
-  relatedList: [],
-  frequencyType: 3,
-  tableData: []
-  // tableData: []
-});
-
-const handleSearchrRelatedNode = id => {
-  if (id == "patrol") {
-    return (state.node = authForm.value);
-  }
-  request
-    .get("/graphService/open/node/related", {
-      params: {
-        id: id,
-        relationship: "回访表单信息"
-      }
-    })
-    .then(resp => {
-      state.relatedList = resp.data;
-      form.related = [];
-    });
-};
-
-const handleAdd = () => {
-  if (!form.node || !form.related.length) {
-    return ElMessage.error("请选择回访项目");
-  }
-  const config = {
-    name: state.nodeList.find(v => v.id == form.node)?.properties.name,
-    content: form.related?.join("、"),
-    frequencyType: state.frequencyType,
-    duration: state.frequencyType == 3 ? dayList.value.join(",") : "",
-    timePreview: "",
-    frequency: 1, // 完后次数
-    remark: "",
-    handle: "",
-    type: 0
-  };
-  state.tableData.push(config);
-  form.node = "";
-  form.related = [];
-  dayList.value = [];
-};
-
-const handleRemove = index => {
-  state.tableData.splice(index, 1);
-};
-
-const getNodeList = async () => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 9999,
-      tag: "可回访"
-    }
-  });
-  const responseData = await request.get(
-    `/idcService/mechanism/formConfig/get`
-  );
-  state.nodeList.value = [];
-
-  if (responseData?.data?.list?.length) {
-    state.nodeList.value = [
-      {
-        id: "patrol",
-        properties: {
-          name: "巡访"
-        },
-        key: "patrol"
-      }
-    ];
-    authForm.value = responseData?.data?.list.map(v => {
-      return {
-        ...v,
-        id: v.formId,
-        properties: {
-          name: v.formTitle
-        }
-      };
-    });
-  }
-  state.nodeList.push(...data.list);
-  console.log("state.nodeList", state.nodeList.value);
-};
-getNodeList();
-</script>
-<style lang="scss " scoped></style>

+ 0 - 239
src/views/healthManagement/components/TrendOfRiskChange.vue

@@ -1,239 +0,0 @@
-<template>
-  <!-- <div class="bg-[#f0f2f5] sticky z-10 top-0 h-4"></div> -->
-  <div
-    class="bg-white p-4 sticky z-10 top-4 flex items-center flex-wrap space-x-2 mr-4 border border-gray-100 rounded"
-  >
-    <el-select v-model="filterDisease" filterable>
-      <el-option label="全部疾病" :value="''"></el-option>
-      <el-option
-        v-for="(item, index) in diseaseList"
-        :key="index"
-        :label="item.name"
-        :value="item.nodeId"
-      ></el-option>
-    </el-select>
-    <!-- <el-select v-model="filter.year">
-      <el-option
-        v-for="(item, index) in 5"
-        :key="index"
-        :label="`最近${index + 1}年数据`"
-        :value="index + 1"
-      ></el-option>
-    </el-select>
-
-    <el-select v-model="filter.dateType">
-      <el-option label="按每年分析统计" :value="1"></el-option>
-      <el-option label="按每半年分析统计" :value="2"></el-option>
-      <el-option label="按每季度分析统计" :value="3"></el-option>
-    </el-select>
-    <el-checkbox
-      v-model="filter.calcBySegment"
-      label="只取统计时间段内的数据进行分析"
-    />
-    <el-tooltip>
-      <QuestionFilled
-        class="w-4 h-4 inline align-middle cursor-pointer opacity-50 outline-none"
-      />
-      <template #content>
-        <div class="text-sm">
-          <p>1、假设当前时间为2023年6月1日,如选择最近3年数据,按每年分析统计</p>
-          <p>2、如果勾选该设置,则系统将会分别取出该用户2023年1月1日至6月1日、2022年1月1日至12月31日、2021年1月1日至12月31日这3年数据分别进行计算后形成分析统计结果</p>
-          <p>3、如果不勾选该设置,则系统分别取出该用户2023年6月1日及其之前所有数据、2022年12月31日及其之前所有数据,2021年12月31日及其之前所有数据分别进行计算后形成分析统计结果</p>
-          <p>4、其他类型统计以此类推</p>
-        </div>
-      </template>
-    </el-tooltip>
-
-    <el-button type="primary" @click="getReportCharts">确定</el-button> -->
-  </div>
-  <div class="mt-6 mr-4">
-    <div
-      v-for="(item, index) in diseaseList"
-      :key="index"
-      class="bg-white p-4 mb-4 border shadow-sm border-gray-100 rounded"
-      :class="{
-        hidden: filterDisease && item.nodeId != filterDisease
-      }"
-    >
-      <div class="h-80 w-full">
-        <Chart
-          :ref="
-            r => {
-              chartRefs[index] = r;
-            }
-          "
-        />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  ref,
-  reactive,
-  inject,
-  nextTick,
-  onMounted,
-  defineAsyncComponent
-} from "vue";
-import dayjs from "dayjs";
-import { useRoute, useRouter } from "vue-router";
-import { QuestionFilled, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-
-import { request, formateArchivesModuleValue, deepClone } from "@/utils";
-import Chart from "@/components/Chart.vue";
-
-const route = useRoute();
-const router = useRouter();
-
-const props = defineProps({
-  nodeId: {
-    type: String,
-    default: ""
-  }
-});
-const filterDisease = ref("");
-const filter = ref({
-  archivesId: route.query.archivesId,
-  dateType: 1,
-  year: 3,
-  calcBySegment: false
-});
-
-const diseaseList = ref([]);
-const medDataList = ref([]);
-const tableHeaderColumns = ref([]);
-const getReportCharts = async () => {
-  const { data } = await request.post(
-    "/idcService/mechanism/archivesReport/charts",
-    filter.value
-  );
-  diseaseList.value = data.detail.diseaseList;
-  medDataList.value = data.detail.medDataList;
-  tableHeaderColumns.value = data.detail.tableHeaderColumns;
-  nextTick(() => {
-    diseaseList.value.forEach((v, i) => {
-      setOption(chartRefs.value[i], v);
-    });
-  });
-};
-
-const init = async () => {
-  getReportCharts();
-};
-const chartRefs = ref([]);
-const setOption = (cRef, item) => {
-  console.log(cRef, item);
-  const opt = {
-    title: {
-      text: item.name + "风险趋势",
-      top: "10",
-      left: "10"
-    },
-    grid: {
-      left: "5%",
-      right: "5%",
-      bottom: "20%"
-    },
-    legend: {
-      top: "bottom"
-    },
-    xAxis: {
-      type: "category",
-      data: tableHeaderColumns.value
-    },
-    tooltip: {
-      formatter(param) {
-        return `${param.seriesName}: ${param.data.label}`;
-      }
-    },
-    yAxis: {
-      type: "value",
-      axisLine: { show: false },
-      axisTick: { show: false },
-      axisLabel: { show: false },
-      max: 6
-    },
-    series: []
-  };
-  if (item.name == "血压") {
-    const arr1 = [];
-    const arr2 = [];
-    item.list.forEach(v => {
-      const val = v.value.split("/");
-      arr1.push({
-        ...v,
-        value: val[0]
-      });
-      arr2.push({
-        ...v,
-        value: val[1]
-      });
-    });
-
-    opt.series = [
-      {
-        name: "收缩压",
-        data: arr1,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      },
-      {
-        name: "舒张压",
-        data: arr2,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      }
-    ];
-  } else {
-    opt.series = [
-      {
-        name: item.name,
-        data: item.list.map(v => ({
-          label: v.riskDesc,
-          value: v.riskDegree
-        })),
-        type: "line",
-        label: {
-          show: true,
-          formatter: param => {
-            return `${param.data.label}`;
-          }
-        },
-        smooth: true
-      }
-    ];
-  }
-  opt.series.forEach(v => {
-    v.data = v.data
-      .map(d => {
-        const val = /(\d+(\.\d+)?)/.exec(String(d.value));
-        if (val) {
-          d.value = val[0] || d.value;
-        }
-        if (isNaN(Number(d.value))) {
-          d.value = null;
-        }
-        return d;
-      })
-      .filter(d => d.value != null);
-  });
-  console.log(opt);
-
-  cRef && cRef.setOption(opt);
-};
-onMounted(() => {
-  init();
-});
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 346
src/views/healthManagement/components/UserDataAnalysis.vue

@@ -1,346 +0,0 @@
-<template>
-  <div v-if="resultRawJson" class="bg-white p-4">
-    <el-descriptions
-      v-if="resultRawJson?.result"
-      title="用户信息"
-      :column="2"
-      border
-      class="mb-8"
-    >
-      <el-descriptions-item label="姓名">{{
-        resultRawJson.result.userInfo.name
-      }}</el-descriptions-item>
-      <el-descriptions-item label="性别">{{
-        resultRawJson.result.userInfo.gender
-      }}</el-descriptions-item>
-      <el-descriptions-item label="体检年龄">{{
-        resultRawJson.result.userInfo.examAge
-      }}</el-descriptions-item>
-      <el-descriptions-item label="体检日期">
-        <!-- {{resultRawJson.result.assessmentDate}} -->
-        {{ dayjs(resultRawJson.result.examDate * 1000).format("YYYY-MM-DD") }}
-      </el-descriptions-item>
-    </el-descriptions>
-    <page-title>
-      <template #icon>
-        <img
-          src="@/assets/riskAnalysis/icon-overflow.png"
-          alt=""
-          class="h-full"
-        />
-      </template>
-      <span>{{ "重大疾病风险概览" }}</span>
-    </page-title>
-    <div v-for="(item, index) in overViewList" :key="index">
-      <div class="break-inside-avoid mb-12">
-        <sub-title :type="rankLabel[item.rank].label">
-          <span>{{ item.title }}</span>
-        </sub-title>
-        <SectionText :type="rankLabel[item.rank].label">{{
-          item.note
-        }}</SectionText>
-      </div>
-
-      <table
-        border="0"
-        v-if="item.children.length"
-        class="border-collapse w-full mb-4 text-sm"
-      >
-        <tr class="page-break-avoid-auto page-break-inside-avoid">
-          <td
-            v-for="(column, columnIndex) in riskTableHeader[item.rank] || [
-              '疾病名称',
-              '患病风险',
-              '重要已知风险因素',
-              '对应科室'
-            ]"
-            :key="columnIndex"
-            class="border border-gray-200 px-2 h-[48px] whitespace-nowrap"
-            :class="rankLabel[item.rank]?.thClass"
-          >
-            {{ column }}
-          </td>
-        </tr>
-        <tr
-          v-for="(child, childIdx) in item.children"
-          :key="childIdx"
-          class="page-break-inside-avoid"
-        >
-          <td class="border border-gray-200">
-            <div class="px-2 py-3">
-              {{ child.name }}
-            </div>
-          </td>
-          <td class="border border-gray-200">
-            <div class="px-2 py-3 whitespace-nowrap">
-              <span :class="riskDegreeLabel[child.riskDegree]?.class">{{
-                // riskDegreeLabel[child.riskDegree].label
-                child.riskDesc
-              }}</span>
-            </div>
-          </td>
-          <template v-if="riskTableHeader[item.rank]">
-            <td class="border border-gray-200">
-              <div class="px-2 py-3">
-                {{
-                  Array.isArray(child.recommendItems)
-                    ? child.recommendItems.join()
-                    : child.recommendItems
-                }}
-              </div>
-            </td>
-          </template>
-          <td v-else class="border border-gray-200">
-            <div class="px-2 py-3">
-              <div
-                v-for="(know, knowIdx) in child.knownFactors"
-                :key="knowIdx"
-                class=""
-              >
-                <span class="align-middle">{{ know.itemName }}:</span>
-                <span class="align-middle">{{
-                  Array.isArray(know.value) ? know.value.join() : know.value
-                }}</span>
-                <el-icon
-                  v-if="know.mark > 0"
-                  class="inline-block align-middle w-4 h-4 text-red-600"
-                  ><Top />
-                </el-icon>
-                <el-icon
-                  v-if="know.mark < 0"
-                  class="inline-block align-middle w-4 h-4 text-green-600"
-                  ><Bottom />
-                </el-icon>
-              </div>
-            </div>
-          </td>
-          <td class="border border-gray-200">
-            <div class="px-2 py-3">
-              {{
-                Array.isArray(child.department)
-                  ? child.department.join("/")
-                  : child.department || "/"
-              }}
-            </div>
-          </td>
-        </tr>
-      </table>
-      <div
-        v-else
-        class="break-inside-avoid flex flex-col items-center justify-center py-6 mb-4 border border-solid border-gray-200 rounded-b"
-      >
-        <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-        <div class="text-gray-500 text-xs text-center mt-4">暂无分析数据</div>
-      </div>
-    </div>
-    <el-empty v-if="!overViewList?.length" description="暂无数据"></el-empty>
-    <UserDataAnalysisEvaluate
-      v-for="(item, index) in 3"
-      :key="index"
-      :classification="index + 1"
-      :latest="true"
-    />
-    <template v-if="suggestion">
-      <page-title :bg="['#1DB198', '#7DFCBC']">
-        <template #icon>
-          <img
-            src="@/assets/riskAnalysis/icon-interpretation.png"
-            alt=""
-            class="h-full"
-          />
-        </template>
-        <span>个性化健康建议</span>
-      </page-title>
-      <div
-        v-if="suggestion"
-        class="relative mb-4 rounded p-4 text-gray-800 leading-6"
-      >
-        <div v-html="suggestion"></div>
-      </div>
-      <div
-        v-else
-        class="break-inside-avoid flex flex-col items-center justify-center py-6 mb-4"
-      >
-        <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-        <div class="text-gray-500 text-xs text-center mt-4">暂无分析数据</div>
-      </div>
-    </template>
-    <component
-      v-if="
-        props.needHorizontal && route.query.archivesId && HorizontalContrast
-      "
-      :is="HorizontalContrast"
-      :archivesId="route.query.archivesId"
-      :hideCtrl="true"
-    >
-      <template #title1>
-        <page-title>
-          <template #icon>
-            <img
-              src="@/assets/riskAnalysis/icon-tumor.png"
-              alt=""
-              class="h-full"
-            />
-          </template>
-          <span>疾病风险评估对比及趋势</span>
-        </page-title>
-      </template>
-      <template #title2>
-        <page-title class="page-break-avoid-auto">
-          <template #icon>
-            <img
-              src="@/assets/riskAnalysis/icon-tumor.png"
-              alt=""
-              class="h-full"
-            />
-          </template>
-          <span>异常项目横向对比</span>
-        </page-title>
-      </template>
-    </component>
-    <template v-if="props.needHorizontal && compareSuggestionStatus == 4">
-      <page-title :bg="['#1DB198', '#7DFCBC']">
-        <template #icon>
-          <img
-            src="@/assets/riskAnalysis/icon-interpretation.png"
-            alt=""
-            class="h-full"
-          />
-        </template>
-        <span>综合个性化健康建议</span>
-      </page-title>
-      <div class="relative mb-4 rounded p-4 text-gray-800 leading-6">
-        <div v-html="compareSuggestion"></div>
-      </div>
-      <!-- <div
-        v-else
-        class="break-inside-avoid flex flex-col items-center justify-center py-6 mb-4"
-      >
-        <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-        <div class="text-gray-500 text-xs text-center mt-4">暂无分析数据</div>
-      </div> -->
-    </template>
-  </div>
-  <el-empty v-else></el-empty>
-</template>
-<script setup>
-import {
-  computed,
-  shallowRef,
-  watch,
-  ref,
-  nextTick,
-  inject,
-  reactive,
-  onMounted,
-  provide,
-  defineAsyncComponent
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { ElMessage, ElMessageBox } from "element-plus";
-import { deduplicateArrayByKeys } from "@/utils";
-import dayjs from "dayjs";
-import PageTitle from "@/components/PageTitle.vue";
-import SubTitle from "@/components/SubTitle.vue";
-import SectionText from "@/components/SectionText.vue";
-import { Top, Bottom } from "@element-plus/icons-vue";
-import UserDataAnalysisEvaluate from "./UserDataAnalysisEvaluate.vue";
-
-const HorizontalContrast = defineAsyncComponent(() =>
-  import("./HorizontalContrast.vue")
-);
-
-const [route, router] = [useRoute(), useRouter()];
-const props = defineProps({
-  needHorizontal: false
-});
-const riskDegreeToRank = {
-  1: [4, 3],
-  2: [2],
-  3: [1],
-  4: [0]
-};
-const riskTableHeader = {
-  3: [
-    "疾病名称",
-    "患病风险",
-    // '建议检查项目',
-    // '建议就医时间',
-    "建议随访项目",
-    // '建议随访时间',
-    "对应科室"
-  ],
-  4: [
-    "疾病名称",
-    "患病风险",
-    "建议完善项目",
-    // '建议完善时间',
-    "对应科室"
-  ]
-};
-const riskDegreeLabel = {
-  4: {
-    label: "已确诊",
-    class: "font-bold text-red-500"
-  },
-  3: {
-    label: "有明显风险",
-    class: "font-bold text-red-600"
-  },
-  2: {
-    label: "有一定风险",
-    class: "font-bold text-yellow-500"
-  },
-  1: {
-    label: "暂未发现风险",
-    class: "text-green-500"
-  },
-  0: {
-    label: "暂未发现风险",
-    class: "text-gray-500"
-  }
-};
-const rankLabel = {
-  1: { label: "danger", thClass: "text-red-500 bg-red-50" },
-  2: { label: "warning", thClass: "text-yellow-500 bg-yellow-50" },
-  3: { label: "primary", thClass: "text-blue-500 bg-blue-50" },
-  4: { label: "warning", thClass: "text-yellow-500 bg-yellow-50" }
-};
-
-const resultRawJson = inject("resultRawJson")
-// const latestReport = inject("latestReport");
-const suggestion = inject("suggestion");
-const compareSuggestion = inject("compareSuggestion");
-const compareSuggestionStatus = inject("compareSuggestionStatus");
-const overViewList = ref();
-
-const formatOverView = () => {
-  overViewList.value = (
-    resultRawJson.value?.result?.reportConfig.reportPreviewCfg.sectionContent ||
-    []
-  )
-    .map(v => {
-      const tempItem = { ...v, children: [] };
-      const children = riskDegreeToRank[v.rank]
-        .map(riskDegree => {
-          return resultRawJson.value.result.majorDisease
-            .filter(v2 => v2.riskDegree == riskDegree)
-            .sort((a, b) => b.riskDegree - a.riskDegree);
-        })
-        .flat();
-      tempItem.children = deduplicateArrayByKeys(children, ["nodeId"]);
-      return tempItem;
-    })
-    .filter(v => v.children.length);
-  console.log("overViewList.value", overViewList.value, resultRawJson.value);
-};
-watch(
-  () => resultRawJson.value,
-  () => {
-    console.log("resultRawJson.value", resultRawJson.value);
-    formatOverView();
-  },
-  { immediate: true }
-);
-</script>
-<style lang="scss"></style>

+ 0 - 272
src/views/healthManagement/components/UserDataAnalysisEvaluate.vue

@@ -1,272 +0,0 @@
-<template>
-  <div class="text-sm">
-    <div v-if="resultRawJson?.result" class="mx-auto space-y-8">
-      <page-title>
-        <template #icon>
-          <img
-            src="@/assets/riskAnalysis/icon-tumor.png"
-            alt=""
-            class="h-full"
-          />
-        </template>
-        <span>{{
-          resultRawJson.result.reportConfig?.[
-            classificationCfg[classification]?.cfgKey
-          ]?.sectionName || "风险评估"
-        }}</span>
-      </page-title>
-
-      <div>
-        <sub-title type="danger" class="break-inside-avoid page-break-auto">
-          <span>{{
-            resultRawJson.result.reportConfig?.[
-              classificationCfg[classification]?.cfgKey
-            ]?.sectionContent[1]?.title || "疾病风险评估及建议"
-          }}</span>
-        </sub-title>
-        <table
-          cellspacing="0"
-          v-if="majorDisease.length"
-          class="border-collapse border border-gray-300 w-full mb-4"
-        >
-          <tr
-            class="page-break-inside-avoid break-inside-avoid page-break-auto"
-          >
-            <td
-              v-for="(column, columnIndex) in [
-                '疾病名称',
-                '患病风险',
-                '建议检查项目',
-                '建议就医时间',
-                '对应科室'
-              ]"
-              :key="columnIndex"
-              class="page-break-inside-avoid border border-gray-200 p-4 text-gray-700 bg-gray-50 whitespace-nowrap"
-            >
-              {{ column }}
-            </td>
-          </tr>
-          <tr
-            v-for="(child, childIdx) in majorDisease"
-            :key="childIdx"
-            class="break-inside-avoid page-break-auto"
-          >
-            <td class="page-break-inside-avoid border border-gray-200">
-              <div class="p-2">
-                {{ child.name }}
-              </div>
-            </td>
-            <td
-              class="page-break-inside-avoid border border-gray-200 min-w-[6em]"
-            >
-              <div class="p-2">
-                <span :class="riskDegreeLabel[child.riskDegree]?.class">{{
-                  child.riskDesc
-                }}</span>
-              </div>
-            </td>
-            <td class="page-break-inside-avoid border border-gray-200">
-              <div class="p-2">
-                {{ (child.recommendItems || []).join("、") || "/" }}
-              </div>
-            </td>
-            <td class="page-break-inside-avoid border border-gray-200">
-              <div class="p-2">
-                {{ child.followUpTime }}
-              </div>
-            </td>
-            <td class="page-break-inside-avoid border border-gray-200">
-              <div class="p-2">
-                {{ (child.department || []).join("/") || "/" }}
-              </div>
-            </td>
-          </tr>
-        </table>
-        <div
-          v-else
-          class="break-inside-avoid page-break-auto flex flex-col items-center justify-center py-6 mb-4 border border-solid border-gray-200 rounded-b"
-        >
-          <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-          <div class="text-gray-500 text-xs text-center mt-4">暂无分析数据</div>
-        </div>
-      </div>
-
-      <div>
-        <sub-title type="primary" class="break-inside-avoid page-break-auto">
-          <span>{{
-            resultRawJson.result.reportConfig?.[
-              classificationCfg[classification]?.cfgKey
-            ]?.sectionContent[3]?.title || "相关数据结果汇总"
-          }}</span>
-        </sub-title>
-        <table
-          cellspacing="0"
-          v-if="medDatas.length"
-          class="border-collapse border border-gray-300 w-full mb-4"
-        >
-          <thead>
-            <tr
-              class="page-break-inside-avoid break-inside-avoid page-break-auto"
-            >
-              <td
-                v-for="(column, columnIndex) in [
-                  '检查名称',
-                  '项目',
-                  '结果',
-                  '单位',
-                  '参考范围',
-                  '检查时间'
-                ]"
-                :key="columnIndex"
-                class="page-break-inside-avoid border border-gray-200 p-4 text-gray-700 bg-gray-50 whitespace-nowrap"
-              >
-                <!-- class="border border-gray-200 px-4 py-2 text-red-500 bg-red-50 whitespace-nowrap" -->
-                {{ column }}
-              </td>
-            </tr>
-          </thead>
-          <tbody>
-            <tr
-              v-for="(child, childIdx) in medDatas"
-              :key="childIdx"
-              class="break-inside-avoid page-break-auto"
-            >
-              <td class="page-break-inside-avoid border border-gray-200">
-                <div class="p-2">
-                  {{ child.checkItemName }}
-                </div>
-              </td>
-              <td class="page-break-inside-avoid border border-gray-200">
-                <div class="p-2">
-                  {{ child.itermName }}
-                </div>
-              </td>
-              <td class="page-break-inside-avoid border border-gray-200">
-                <div class="p-2">
-                  {{ child.value }}
-                </div>
-              </td>
-              <td class="page-break-inside-avoid border border-gray-200">
-                <div class="p-2">
-                  {{ child.unit }}
-                </div>
-              </td>
-              <td class="page-break-inside-avoid border border-gray-200">
-                <div class="p-2">
-                  {{ child.reference }}
-                </div>
-              </td>
-              <td
-                class="page-break-inside-avoid border border-gray-200 whitespace-nowrap"
-              >
-                <div class="p-2">
-                  {{
-                    dayjs(new Date(child.checkTime * 1000)).format("YYYY-MM-DD")
-                  }}
-                </div>
-              </td>
-            </tr>
-          </tbody>
-        </table>
-        <div
-          v-else
-          class="break-inside-avoid page-break-auto flex flex-col items-center justify-center py-6 mb-4 border border-solid border-gray-200 rounded-b"
-        >
-          <img src="@/assets/riskAnalysis/empty-img.png" class="w-40" />
-          <div class="text-gray-500 text-xs text-center mt-4">暂无分析数据</div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { ref, shallowRef, watch, inject } from "vue";
-import { deduplicateArrayByKeys } from "@/utils";
-import dayjs from "dayjs";
-import PageTitle from "@/components/PageTitle.vue";
-import SubTitle from "@/components/SubTitle.vue";
-const data = shallowRef();
-
-const props = defineProps({
-  classification: {
-    type: Number
-  },
-  latest: {
-    type: Boolean,
-    default: false
-  }
-});
-const resultRawJson = props.latest
-  ? inject("latestResultRawJson")
-  : inject("resultRawJson");
-console.log("xxxx", resultRawJson);
-const riskDegreeLabel = {
-  4: {
-    label: "已确诊",
-    class: "font-bold text-red-500"
-  },
-  3: {
-    label: "有明显风险",
-    class: "font-bold text-red-600"
-  },
-  2: {
-    label: "有一定风险",
-    class: "font-bold text-yellow-500"
-  },
-  1: {
-    label: "暂未发现风险",
-    class: "font-bold text-green-500"
-  },
-  0: {
-    label: "暂未发现风险",
-    class: "font-bold text-gray-500"
-  }
-};
-let classification = Number(props.classification || 1);
-const classificationCfg = {
-  1: {
-    cfgKey: "reportCancerCfg"
-  },
-  2: {
-    cfgKey: "reportCardiovascularCfg"
-  },
-  3: {
-    cfgKey: "reportPersonaliseCfg"
-  }
-};
-const majorDisease = ref([]);
-const abnormalDatas = ref([]);
-const medDatas = ref([]);
-const formatList = () => {
-  const major = resultRawJson.value.result.majorDisease
-    .filter(v2 => v2.classification === classification)
-    .sort((a, b) => b.riskDegree - a.riskDegree);
-  majorDisease.value = deduplicateArrayByKeys(major, ["nodeId"]);
-  const abnormalData = majorDisease.value
-    .map(v => v.abnormalDatas)
-    .flat()
-    .filter(v => v);
-  abnormalDatas.value = deduplicateArrayByKeys(abnormalData, ["nodeId"]);
-  const medData = majorDisease.value
-    .map(v => v.medDatas)
-    .flat()
-    .filter(v => v);
-  medDatas.value = deduplicateArrayByKeys(medData, ["nodeId", "checkItemId"]);
-  console.log("xxxx", majorDisease.value, abnormalDatas.value, medDatas.value);
-};
-
-watch(
-  () => resultRawJson.value,
-  () => {
-    if (resultRawJson.value && resultRawJson.value.result) {
-      formatList();
-    }
-  },
-  {
-    immediate: true
-  }
-);
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 1222
src/views/healthManagement/components/customSurvey.vue

@@ -1,1222 +0,0 @@
-<template>
-  <div ref="home" class="home">
-    <div class="dialogue-list">
-      <el-scrollbar height="calc(50vh)">
-        <div
-          v-for="(item, surveyIndex) in showList"
-          :key="surveyIndex"
-          class="dialogue-item m-1 bg-gray-100 rounded p-4 mb-3"
-        >
-          <QuestionItem
-            :info="item"
-            :hide-list="hideList"
-            :repeat-answer="item.isAnswered && lastIndex === surveyIndex"
-            class="dialogue-content"
-            @skip="skip"
-            @back="back"
-            @reply="reply"
-            @check="check"
-          />
-        </div>
-      </el-scrollbar>
-      <div class="text-right">
-        <div class="dialogue-content">
-          <span>{{ state.detail.endingText }}</span>
-          <el-button
-            block
-            type="primary"
-            @click="save"
-            :loading="state.loading"
-          >
-            提交
-          </el-button>
-        </div>
-      </div>
-      <!-- <template v-if="state.inputLoading">
-        <div
-          class="dialogue-item animate__animated animate__faster animate__slideInLeft"
-        >
-          <van-image class="avatar" :src="state.detail.systemAvatar" />
-
-          <div class="dialogue-content">
-            <span>...</span>
-          </div>
-        </div>
-      </template> -->
-    </div>
-  </div>
-</template>
-
-<script setup>
-// import { resolvingDslDecision, surveyByCode } from '../utils/axios'
-import { request, parseJSON, deepClone, debounceWithImmediate } from "@/utils";
-// import { showNotify, Toast, showConfirmDialog } from "vant";
-
-import QuestionItem from "./questionItem.vue";
-import dayjs from "dayjs";
-import {
-  onMounted,
-  nextTick,
-  computed,
-  watch,
-  ref,
-  reactive,
-  defineProps,
-  defineEmits
-} from "vue";
-import { unique } from "@/utils/index";
-import { useRoute, useRouter } from "vue-router";
-import { ElMessage } from "element-plus";
-const QUESTION_TYPE_TEMP_CHECK = "temp_check";
-const QUESTION_TYPE_ANSWER = "answer";
-const QUESTION_TYPE_INPUT = "input";
-const QUESTION_TYPE_TEXT = "text";
-const QUESTION_TYPE_CHECKBOX = "checkbox";
-const QUESTION_TYPE_RADIO = "radio";
-const QUESTION_TYPE_SELECT = "select";
-const QUESTION_TYPE_RATING_SCALE = "rating_scale";
-const QUESTION_TYPE_RATING = "rating";
-const QUESTION_TYPE_DATE = "date";
-const QUESTION_TYPE_UPLOAD = "upload";
-const QUESTION_TYPE_MATRIX = "matrix_checkbox";
-const QUESTION_TYPE_COMBINATION = "combination";
-const QUESTION_TYPE_GROUP = "group"; // 组合题
-const route = useRoute();
-const router = useRouter();
-const emits = defineEmits(["onSave"]);
-const props = defineProps({
-  content: {
-    type: Object,
-    default: () => {
-      return {
-        content: {},
-        logicCode: {}
-      };
-    }
-  }
-});
-const state = reactive({
-  loading: false,
-  detail: {
-    id: "",
-    title: "",
-    sn: "",
-    questions: [],
-    survey_rules: {
-      status: ""
-    },
-    greetingText: "",
-    endingText: "",
-    memberAvatar: "",
-    systemAvatar: "",
-    peg: "",
-    updated_at: ""
-  },
-  questionResult: {
-    id: "",
-    surveyMechanismId: ""
-  },
-  index: 0,
-  isFinished: false,
-  loading: null,
-  inputLoading: false,
-  survey_id: "",
-  replyLock: false,
-  logicRulesList: []
-});
-const currentValue = ref("");
-const rawList = ref([]);
-const showList = ref([]);
-const _showList = ref([]);
-const noAnswer = computed(() =>
-  showList.value.filter(
-    v =>
-      ![
-        QUESTION_TYPE_TEXT,
-        QUESTION_TYPE_ANSWER,
-        QUESTION_TYPE_TEMP_CHECK
-      ].includes(v.type)
-  )
-);
-const hideList = ref([]);
-
-const lastIndex = computed(() => {
-  for (let i = showList.value.length - 1; i >= 0; i--) {
-    if (showList.value[i]?.isAnswered) {
-      return i;
-    }
-  }
-  return 0;
-});
-
-const rules = ref([]);
-const checkDisabled = ref(false);
-
-const home = ref();
-
-const pushText = (text, time, isHtml = false) => {
-  return new Promise((resolve, reject) => {
-    showList.value.push({
-      title: text,
-      config: {
-        desc: "",
-        required: true
-      },
-      isHtml,
-      type: QUESTION_TYPE_TEXT
-    });
-    setTimeout(() => {
-      resolve(1);
-    }, time || 8e2);
-  });
-};
-
-const skip = item => {
-  console.log(item);
-  item.isAnswered = true;
-  item.isSkip = true;
-  next(item);
-};
-const back = item => {
-  if (state.replyLock) return;
-  const backList = rules.value[`QU${item.code}`]
-    ?.filter(v => v.method === "hide" && v.expression.includes(item.code))
-    .map(v => v.question)
-    .flat();
-  console.log(item);
-  console.log(rules.value[`QU${item.code}`]);
-  console.log(hideList.value);
-
-  console.log(backList);
-  if (backList?.length) {
-    backList.forEach(k => {
-      const delIdx = hideList.value.findIndex(v => v == k);
-      delIdx >= 0 && hideList.value.splice(delIdx, 1);
-    });
-  }
-  showList.value.splice(
-    lastIndex.value + 1,
-    showList.value.length - lastIndex.value
-  );
-  item.isAnswered = false;
-  item.value = "";
-  state.isFinished = false;
-};
-
-const scrollToLast = () => {
-  const last = home.value?.querySelector(".dialogue-item:last-of-type");
-  home.value?.scrollTo(
-    0,
-    last ? last.offsetTop - 40 : home.value?.scrollHeight
-  );
-};
-const check = (item, flag) => {
-  if (item.isRepeat) {
-    repeat(item, flag);
-  } else if (item.isEnd) {
-    console.log(item);
-    showList.value.splice(showList.value.length - 1, 1);
-    if (flag) {
-      state.isFinished = true;
-    } else {
-      next(noAnswer.value.at(-1), false);
-    }
-    scrollToLast();
-  }
-};
-
-const repeat = (item, flag) => {
-  console.log(item);
-  if (flag) {
-    showList.value.splice(showList.value.length - 1, 1);
-    nextTick(() => {
-      const item = JSON.parse(JSON.stringify(noAnswer.value.at(-1)));
-      if (
-        item.type === QUESTION_TYPE_COMBINATION ||
-        item.type === QUESTION_TYPE_GROUP
-      ) {
-        item.children = item.children.map(v => {
-          v.value = Array.isArray(v.value) ? [] : "";
-          return v;
-        });
-      }
-      // showList.value.push({
-      //   ...item,
-      //   isAnswered: false,
-      //   value: ""
-      // });
-      // scrollToLast();
-    });
-  } else {
-    showList.value.splice(showList.value.length - 1, 1);
-    next(noAnswer.value.at(-1));
-  }
-};
-
-const reply = (item, text) => {
-  if (currentValue.value === item.value) return;
-  currentValue.value = item.value;
-
-  // showList.value.push({
-  //   left: false,
-  //   title: text,
-  //   type: QUESTION_TYPE_ANSWER,
-  //   isAnswered: true,
-  //   isRequired: true,
-  //   config: {
-  //     required: true
-  //   }
-  // });
-  if (item.isRepeat) {
-    showList.value.push({
-      title: "是否再增加一条记录?",
-      config: {
-        desc: "",
-        required: true
-      },
-      isRepeat: true,
-      type: QUESTION_TYPE_TEMP_CHECK
-    });
-    console.log(showList.value);
-    scrollToLast();
-    return;
-  }
-  initShowList();
-};
-const initShowList = () => {
-  if (state.loading) return;
-  state.loading = true;
-  hideList.value = [];
-  state.logicRulesList = [rawList.value[0]];
-  _showList.value = unique([...rawList.value, ...showList.value], "sn");
-
-  _showList.value?.map(item => {
-    next(item);
-  });
-  setTimeout(() => {
-    showList.value = removeDataBetweenDuplicates(state.logicRulesList, "sn");
-    state.loading = false;
-  }, 1000);
-};
-const getItem = code => {
-  code = code.replace(/^QU/, "");
-  return rawList.value.find(v => v.sn === code);
-};
-const getQ = code => {
-  code = code.replace(/^QU/, "");
-  const items = showList.value.filter(v => v.sn === code);
-  const item = getItem(code);
-  console.log(showList.value);
-  console.log(items);
-  if (items.length > 1) {
-    return items.map(formatItemVal);
-  }
-  const val = item.value;
-
-  if (item.type === QUESTION_TYPE_RADIO) {
-    return [val];
-  } else if (item.type === QUESTION_TYPE_CHECKBOX) {
-    return val || [];
-  }
-  return item.value;
-};
-
-const getS = number => {
-  const q = number.match(/Q\d+/)[0];
-  const s = Number(number.match(/S\d+/)[0]?.slice(1)) - 1;
-  const a = number.includes("A")
-    ? Number(number.match(/A\d+/)[0].slice(1)) - 1
-    : "";
-  console.log(
-    `当前获取${number} 获取到的q: ${q} ,获取到的s: ${s} ,获取到的a: ${a}`
-  );
-  return a ? getItem(q).matrix[s][a] : getItem(q).matrix[s];
-};
-
-const getA = number => {
-  const q = number.match(/Q\d+/)[0];
-  const a = Number(number.match(/A\d+/)[0].slice(1)) - 1;
-  console.log(`当前获取${number} 获取到的q: ${q} ,获取到的a: ${a}`);
-  console.log(`获取到的q:`);
-  console.log(Array.isArray(getQ(q)), getQ(q), typeof a, a);
-  const qVal = Array.isArray(getQ(q)) ? getQ(q).map(String) : getQ(q) || "";
-  return qVal.includes(String(a));
-};
-
-const getVal = code => {
-  // return number.includes('S') ? getS(number) .includes('A') ? getA(number) : getQ(number)
-  return getQ(code);
-};
-
-const getRuleKey = type => {
-  switch (type) {
-    case "showHide":
-    case "to":
-      return "expression";
-    case "say":
-    case "replace":
-      return "keyword";
-    default:
-      return "";
-  }
-};
-const formatAge = birthday => {
-  if (!birthday) return "";
-  if (!isNaN(Number(birthday))) return birthday;
-  const offset = +new Date() - +new Date(birthday.replace(/-/g, "/"));
-  return parseInt(String(offset / 86400000 / 365));
-};
-const chooseAnd = (itemVal, ...choices) => {
-  for (const idx of choices) {
-    if (!itemVal.includes(idx)) return false;
-  }
-  return true;
-};
-const chooseOr = (itemVal, ...choices) => {
-  for (const idx of choices) {
-    if (itemVal.includes(idx)) return true;
-  }
-  return false;
-};
-const chooseMatrix = (itemVal, ...values) => {
-  for (const v of values) {
-    if (!itemVal.includes(v)) return false;
-  }
-  return true;
-};
-const chooseMatrixOr = (itemVal, ...values) => {
-  for (const v of values) {
-    if (!itemVal.includes(v)) return true;
-  }
-  return false;
-};
-const isEmpty = val => {
-  if (Array.isArray(val)) {
-    return !val.length;
-  }
-  if (val === 0) return false;
-  return !val;
-};
-const count = arg => (typeof arg == "number" ? arg : arg.length);
-
-window["formatAge"] = formatAge;
-window["chooseAnd"] = chooseAnd;
-window["chooseOr"] = chooseOr;
-window["chooseMatrix"] = chooseMatrix;
-window["chooseMatrixOr"] = chooseMatrixOr;
-window["isEmpty"] = isEmpty;
-const formatQuKey = key => (/^QU/.test(key) ? key.replace(/^QU/, "") : key);
-const customFunc = [
-  "formatAge",
-  "chooseAnd",
-  "chooseOr",
-  "chooseMatrix",
-  "count"
-];
-const formatRule = rule => {
-  const getQAReg = new RegExp(/QU(\w+)?/gi);
-  let rawCondition = rule[getRuleKey(rule.type)] || "";
-  rawCondition = rawCondition
-    .replace(/ and /g, " && ")
-    .replace(/ or /g, " || ");
-
-  let condition = rawCondition;
-  let replaceReg = undefined;
-  let qa = [];
-  if (condition) {
-    console.log(
-      `%c当前的规则: ${condition}`,
-      "font-size: 16px; color: #4b72f6;"
-    );
-
-    qa = rawCondition.match(getQAReg) || [];
-    console.log(`当前的qa:`, qa);
-    qa.map(n => {
-      const code = formatQuKey(n);
-      const curItem = getItem(code);
-      const v = getVal(code);
-      console.log("获取到的值:", n, ":", v);
-      // 存在自定义方法
-      for (const func of customFunc) {
-        if (condition.includes(func)) {
-          // 选择类方法
-          if (/^choose/.test(func)) {
-            if (func.includes("Matrix")) {
-              curItem.rows.forEach(row => {
-                curItem.columns.forEach(col => {
-                  const matrixAttr = row.attr + col.attr;
-                  if (condition.includes(matrixAttr)) {
-                    condition = condition.replace(
-                      new RegExp(matrixAttr),
-                      `"${row.label + col.label}"`
-                    );
-                  }
-                });
-              });
-            } else {
-              let sortChoices = curItem.choices.map((v, k) => {
-                return {
-                  ...v,
-                  index: k
-                };
-              });
-              sortChoices = sortChoices.sort(
-                (a, b) => b.attr.length - a.attr.length
-              );
-              sortChoices.forEach(v => {
-                if (condition.includes(v.attr)) {
-                  condition = condition.replace(new RegExp(v.attr), v.index);
-                }
-              });
-            }
-          }
-        }
-      }
-      const reg = new RegExp(n);
-      console.log(`要执行的正则`, reg, v);
-      condition = condition.replace(
-        reg,
-        Array.isArray(v)
-          ? `[${v
-              .map(v2 => (typeof v2 === "string" ? `'${v2}'` : v2))
-              .join(",")}]`
-          : typeof v === "string"
-          ? `'${v}'`
-          : v
-      );
-      console.log(condition);
-    });
-
-    console.log(`获取到的qa`);
-    console.log(qa);
-    console.log(`最后的condition`);
-    console.log(condition);
-  }
-  let flag = false;
-  try {
-    flag = eval(condition);
-  } catch (e) {
-    console.log(e);
-
-    flag = false;
-  }
-  console.log(`当前规则执行的flag: %c ${flag}`, "color: #f00;");
-
-  console.log(`执行---------------${rule.type} -----------规则: ${condition}`);
-  switch (rule.type) {
-    case "showHide":
-      if (flag) {
-        if (rule.method == "hide") {
-          hideList.value.push(
-            ...(Array.isArray(rule.question) ? rule.question : [rule.question])
-          );
-        } else {
-          return {
-            type: "to",
-            to: rule.question
-          };
-        }
-      }
-      break;
-    case "to":
-      return flag
-        ? {
-            type: "to",
-            to: rule.to
-          }
-        : undefined;
-    case "say":
-      if (flag) {
-        return {
-          type: "say",
-          say: rule.say
-        };
-      }
-      break;
-
-    case "replace":
-      replaceReg = new RegExp(rule.keyword);
-      console.log(`执行正则: ${rule.keyword}`);
-
-      {
-        let t = undefined;
-        const q = getItem(rule.from);
-        console.log(`当前replace-q: `);
-        console.log(q);
-        if (rule.index >= 0) {
-          console.log(q["choices"][rule.index - 1]);
-          t = q["choices"][rule.index - 1]?.label;
-        } else {
-          if (q["choices"]) {
-            t = q["choices"][Number(getQ(rule.from))].label;
-          } else {
-            t = q.value;
-          }
-        }
-        console.log(`获取到的t: ${t}`);
-
-        getItem(rule.to).title = getItem(rule.to).title?.replace(
-          replaceReg,
-          Array.isArray(t) ? t.join(",") : t
-        );
-      }
-      break;
-    case "end":
-      showList.value.push({
-        title: "是否结束答题?",
-        config: {
-          desc: "",
-          required: true
-        },
-        isEnd: true,
-        type: QUESTION_TYPE_TEMP_CHECK
-      });
-      return {
-        type: "end"
-      };
-  }
-};
-const removeDataBetweenDuplicates = (array, key = "id") => {
-  const seenIds = new Set(); // 存储已经遍历到的id
-  const result = []; // 新数组
-
-  for (let i = 0; i < array.length; i++) {
-    const currentId = array[i][key];
-
-    if (!seenIds.has(currentId)) {
-      // 如果 id 没有出现过,加入结果集
-      result.push(array[i]);
-      seenIds.add(currentId); // 标记为已见过
-    } else {
-      // 如果发现了重复的 id,删除当前结果集之后重复 id 之前的数据
-      const duplicateIndex = result.findIndex(item => item[key] === currentId);
-      result.splice(duplicateIndex + 1);
-    }
-  }
-
-  return result;
-};
-
-const next = async (item, runRule = true, index) => {
-  state.replyLock = true;
-  console.log("规则判断");
-  const rule = rules.value[`QU${item.sn}`];
-  console.log(rules.value);
-  console.log(rule);
-  console.log("当前item");
-  console.log(item);
-  console.log(getItem(item.sn));
-  console.log(getQ(item.sn));
-  console.time("规则执行");
-  console.log("==================start=====================");
-  let to = undefined;
-  try {
-    if (runRule) {
-      for (const i in rule || []) {
-        console.log("执行规则", i + 1, "-----type:", rule[i].type);
-        const res = formatRule(rule[i]) || {};
-        switch (res.type) {
-          case "to":
-            to = res.to || undefined;
-            break;
-          case "say":
-            res.say && (await pushText(res.say || "", 0, true));
-            break;
-          case "end":
-            state.replyLock = false;
-            return;
-        }
-      }
-    }
-  } catch (e) {
-    console.log("报错了");
-    console.log(e);
-    // showNotify(e?.message);
-    ElMessage.error(e?.message);
-  }
-  console.log("==================end=======================");
-  console.log(to);
-  console.timeEnd("规则执行");
-
-  state.inputLoading = true;
-  nextTick(() => {
-    setTimeout(() => {
-      state.inputLoading = false;
-      if (to) {
-        console.log("存在to跳转", to);
-        if (to.toLocaleLowerCase() === "end") {
-          state.isFinished = true;
-        } else {
-          console.log("to跳转", getItem(to));
-          // showList.value.push(getItem(to));
-          state.logicRulesList.push(getItem(to));
-          // showList.value.splice(state.index, spliceIndex);
-        }
-      } else {
-        console.log("不存在to跳转");
-        console.log(hideList.value);
-        // state.index = Number(item.number.match(/Q\d+/gi)[0].slice(1))
-        state.index = findNoHideQuestion(
-          rawList.value.findIndex(v => v.sn == item.sn) + 1
-        );
-        console.log(`当前index: ${state.index}`);
-        console.log(rawList.value[state.index]);
-        if (state.index >= rawList.value.length) {
-          state.isFinished = true;
-        } else {
-          // showList.value.push(rawList.value[state.index]);
-          state.logicRulesList.push(rawList.value[state.index]);
-        }
-      }
-      state.replyLock = false;
-      localStorage.setItem(
-        `temp_q3_${route.query.id}`,
-        JSON.stringify({
-          state,
-          rawList: rawList.value,
-          showList: showList.value,
-          hideList: hideList.value,
-          rules: rules.value
-        })
-      );
-      console.log("logicRulesList", state.logicRulesList);
-      console.log("logicRulesList", showList.value);
-
-      nextTick(() => {
-        scrollToLast();
-        if (state.isFinished) return;
-      });
-    }, 500);
-  });
-};
-const findNoHideQuestion = index => {
-  if (index >= rawList.value.length) return rawList.value.length;
-  if (hideList.value.includes(`QU${rawList.value[index].sn}`)) {
-    return findNoHideQuestion(index + 1);
-  } else {
-    return index;
-  }
-};
-const recover = async () => {
-  const tempQuestions = JSON.parse(
-    localStorage.getItem(`temp_q3_${route.query.id}`)
-  );
-  if (tempQuestions) {
-    if (tempQuestions?.state?.detail?.updated_at != state?.detail?.updated_at) {
-      return localStorage.removeItem(`temp_q3_${route.query.id}`);
-    }
-    console.log("存在缓存题目");
-    return;
-    const dialog = await showConfirmDialog({
-      title: "提示",
-      message: "存在答题记录,是否使用之前的答题记录?",
-      confirmButtonColor: "#4B72F6"
-    }).catch(() => {});
-
-    if (dialog === "confirm") {
-      Object.keys(tempQuestions.state).forEach(key => {
-        if (key != "questionResult") {
-          state[key] = tempQuestions.state[key];
-        }
-      });
-
-      rawList.value = tempQuestions.rawList;
-      showList.value = tempQuestions.showList;
-      hideList.value = tempQuestions.hideList;
-      rules.value = tempQuestions.rules;
-      setTimeout(() => {
-        scrollToLast();
-      }, 0);
-    }
-  }
-};
-const formatResultList = arr => {
-  console.log("formatResultList执行成功", arr);
-
-  const list = [];
-  const repeatKey = [];
-
-  arr.forEach(v => {
-    if (v.isRepeat) {
-      if (!repeatKey.includes(v.sn)) {
-        const temp = {
-          ...v,
-          value: []
-        };
-        repeatKey.push(v.sn);
-        const cur = arr.filter(v2 => v2.sn === v.sn);
-        console.log("cur", cur);
-
-        temp.value = cur.map(formatItemVal);
-
-        temp.rawValue = cur.map(v2 => {
-          if (v.type == QUESTION_TYPE_GROUP) {
-            return v2.children.map(v3 => v3.value);
-          } else {
-            return v2.value;
-          }
-        });
-        console.log(temp.value, temp.rawValue);
-        list.push(temp);
-      }
-    } else {
-      console.log(v.type == QUESTION_TYPE_GROUP && "出现组合题", v);
-      if (v.type == QUESTION_TYPE_GROUP) {
-        list.push({
-          ...v,
-          rawValue: v.children.map(child => child.value),
-          value: formatItemVal(v)
-        });
-      } else {
-        list.push({
-          ...v,
-          rawValue: v.value,
-          value: formatItemVal(v)
-        });
-      }
-    }
-  });
-  return list;
-};
-const formatItemVal = item => {
-  if (item.type === QUESTION_TYPE_GROUP) {
-    item.value = item.children.map(v => formatItemVal(v));
-    return item.value;
-  } else if (item.type === QUESTION_TYPE_MATRIX) {
-    const res = [];
-    item.matrix?.forEach((cols, k1) => {
-      cols &&
-        cols.forEach &&
-        cols?.forEach((c, k2) => {
-          c && res.push(item.rows[k1].label + "" + item.columns[k2].label);
-        });
-    });
-    return res;
-  } else if (item["choices"]?.length) {
-    return Array.isArray(item.value)
-      ? item.value.map(c =>
-          item["choices"][c]?.isInput
-            ? item["choices"][c]?.extra
-            : item["choices"][c]?.label
-        )
-      : item["choices"][item.value]?.isInput
-      ? item["choices"][item.value]?.extra
-      : item["choices"][item.value]?.label;
-  } else {
-    return item.value;
-  }
-};
-const formatResultDataItem = item => {
-  const resultItem = {
-    multipleAnswers: item.isRepeat,
-    type: item.type,
-    questionNo: item.sn,
-    checkboxAnswers: null,
-    inputAnswers: null,
-    matrixAnswers: null,
-    linkAnswers: null,
-    groupAnswers: null,
-    answer: undefined
-  };
-  switch (item.type) {
-    case QUESTION_TYPE_CHECKBOX:
-      {
-        const tmp = [];
-        if (Array.isArray(item.rawValue)) {
-          item.rawValue?.forEach((childIdx, k) => {
-            const findChoices = item.choices[childIdx];
-            tmp.push({
-              key: findChoices?.attr,
-              value: item.value[k]
-            });
-          });
-        }
-        resultItem.checkboxAnswers = tmp;
-      }
-      break;
-    case QUESTION_TYPE_RADIO:
-      {
-        resultItem.answer = {
-          key: item.choices[item.rawValue]?.attr,
-          value: item.value
-        };
-      }
-      break;
-    case QUESTION_TYPE_SELECT:
-      {
-        resultItem.checkboxAnswers = item.value || [];
-      }
-      break;
-    case QUESTION_TYPE_INPUT:
-      {
-        const tmp = {
-          key: item.attr,
-          value: []
-        };
-        if (item.isRepeat) {
-          item.value?.forEach(val => {
-            tmp.value.push(val);
-          });
-        } else {
-          tmp.value = Array.isArray(item.value) ? item.value : [item.value];
-        }
-        tmp.value = tmp.value.map(String);
-        resultItem.inputAnswers = tmp;
-      }
-      break;
-    case QUESTION_TYPE_UPLOAD:
-      {
-        const tmp = {
-          key: item.attr,
-          value: []
-        };
-        tmp.value = Array.isArray(item.value) ? item.value : [item.value];
-        resultItem.linkAnswers = tmp;
-      }
-      break;
-    case QUESTION_TYPE_DATE:
-      {
-        resultItem.answer = {
-          key: item.attr,
-          value: Array.isArray(item.value) ? item.value[0] : item.value
-        };
-      }
-      break;
-    case QUESTION_TYPE_MATRIX:
-      resultItem.matrixAnswers = [];
-      item.matrix.forEach((cols, k1) => {
-        cols.forEach((check, k2) => {
-          if (check) {
-            resultItem.matrixAnswers.push({
-              xKey: item.rows[k1].attr,
-              xText: item.rows[k1].label,
-              yKey: item.columns[k2].attr,
-              yText: item.columns[k2].label
-            });
-          }
-        });
-      });
-      break;
-    case QUESTION_TYPE_GROUP:
-      resultItem.groupAnswers = [];
-      (item.isRepeat ? item.value : [item.value])?.forEach((val, k) => {
-        const temp = [];
-        item.children.forEach((child, childIdx) => {
-          temp.push(
-            formatResultDataItem({
-              ...child,
-              rawValue: item.isRepeat
-                ? item.rawValue[k][childIdx]
-                : item.rawValue[childIdx],
-              value: val[childIdx]
-            })
-          );
-        });
-        resultItem.groupAnswers.push(temp);
-      });
-      break;
-  }
-  console.log(item, resultItem);
-  return resultItem;
-};
-const formatData = list => {
-  const result = {};
-  list.forEach(v => {
-    result[v.sn] = formatResultDataItem(v);
-  });
-  return result;
-};
-const startTime = ref();
-const save = async () => {
-  state.loading = true;
-  const list = formatResultList(noAnswer.value);
-  // const _ruleList = unique(state.logicRulesList, "sn");
-  // console.log("_ruleList", _ruleList);
-  setTimeout(() => {
-    const isAllAnswer = list?.some(v => {
-      return v.config.required && !isNonZero(v.value);
-    });
-    state.loading = false;
-    if (isAllAnswer) {
-      return ElMessage.error("请回答问卷必答题");
-    }
-    emits("onSave", {
-      questions: _showList.value,
-      viewQuestions: list
-    });
-  }, 700);
-
-  return;
-  const { data } = await request.post(
-    "/surveyService/member/customSurvey/answer",
-    {
-      surveyId: route.query.id,
-      startTime: startTime.value,
-      answerRaw: JSON.stringify(list)
-    }
-  );
-  router.push({
-    name: route.query.redirectPath || "customResult",
-    query: {
-      id: data.id,
-      surveyMechanismId: route.query.id,
-      _r: Date.now(),
-      back: route.query.token ? undefined : 1
-    }
-  });
-};
-
-const isNonZero = value => {
-  // 检验值是否为空(null, undefined, "" 或者 false)
-  if (value == null || value === "" || value === false) {
-    return false;
-  }
-  // 对于对象,检验是否有属性
-  if (typeof value === "object" && Object.keys(value).length === 0) {
-    return false;
-  }
-  // 其他情况视为非空
-  return true;
-};
-const init = async () => {
-  startTime.value = dayjs(Date.now()).format("YYYY-MM-DD HH:mm:ss");
-  // const { data: surveyData } = await request.get(
-  //   "/surveyService/member/customSurvey/detail",
-  //   {
-  //     params: route.query
-  //   }
-  // );
-
-  const surveyData = {
-    detail: {
-      content: {
-        content: [],
-        logicCode: []
-      }
-    }
-  };
-
-  if (props.content?.content) {
-    surveyData.detail.content.content = deepClone(props.content?.content || []);
-  }
-  if (props?.content?.logicCode) {
-    surveyData.detail.content.logicCode = deepClone(
-      props?.content?.logicCode || []
-    );
-  }
-  state.detail = surveyData.detail;
-  state.detail.questions = surveyData.detail.content.content;
-  console.log("state.detail.questions", state.detail.questions);
-  // showList.value = [state.detail.questions[0]];
-  rawList.value = state.detail.questions;
-  // let peg = null;
-  // try {
-  //   peg = state.detail.peg ? JSON.parse(state.detail.peg) : {};
-  // } catch (e) {
-  //   console.log(e);
-  //   peg = {};
-  // }
-  const r = {};
-  surveyData.detail.content.logicCode?.length &&
-    surveyData.detail.content.logicCode.forEach(v => {
-      const code = `QU${v.condition}`;
-      if (!r[code]) {
-        r[code] = [];
-      }
-      r[code].push(v);
-    });
-
-  console.log("props?.content?.logicCode", props?.content?.logicCode);
-
-  rules.value = r;
-  console.log("state.detail");
-  console.log(state.detail);
-  console.log("rules.value");
-  console.log(rules.value);
-
-  showList.value = rawList.value;
-  showList.value?.forEach(v => {
-    if (isNonZero(v?.rawValue)) {
-      v.value = v.rawValue;
-    }
-  });
-  initShowList();
-  console.log("showList", showList.value);
-  console.log("hideList", hideList.value);
-};
-onMounted(() => {
-  if ("scrollRestoration" in history) {
-    history.scrollRestoration = "manual";
-  }
-  // route.query.token && setSurveyToken(route.query.token);
-  // inputBlur();
-  // init();
-});
-defineExpose({
-  init
-});
-</script>
-
-<style lang="scss">
-body {
-  // height: 100%;
-  -moz-osx-font-smoothing: grayscale;
-  -webkit-font-smoothing: antialiased;
-  text-rendering: optimizeLegibility;
-  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
-    Microsoft YaHei, Arial, sans-serif;
-  background: #f6f9ff;
-  overflow-x: hidden;
-}
-.home {
-  overflow-x: hidden;
-  overflow-y: auto;
-  box-sizing: border-box;
-  .dialogue-list {
-    box-sizing: border-box;
-    padding-top: 20px;
-  }
-  .dialogue-item {
-    display: flex;
-    justify-content: flex-start;
-    align-items: flex-start;
-    margin-bottom: 15px;
-    transition: all 0.3s linear;
-    transform: translateZ(0);
-  }
-  .survey-title {
-    font-size: 15px;
-  }
-  .survey-desc {
-    font-size: 12px;
-    color: #666;
-    margin-top: 5px;
-  }
-  .survey-tag {
-    position: absolute;
-    right: 0;
-    top: 0;
-    color: #fff;
-    padding: 4px 10px;
-    font-size: 12px;
-    border-radius: 0 10px 0 10px;
-    background: linear-gradient(to right, #fea36c 0%, #fb7654 100%);
-  }
-  .avatar {
-    border-radius: 4px;
-    width: 45px;
-    height: 45px;
-    margin: 0 10px;
-    overflow: hidden;
-    border-radius: 50%;
-  }
-  .dialogue-content {
-    // max-width: 70%;
-    width: 100%;
-    border-radius: 10px;
-    border-top-left-radius: 0;
-    background: #fff;
-    // box-shadow: 1px 1px 2px #ccc;
-    padding: 10px;
-    box-sizing: border-box;
-    position: relative;
-    img {
-      max-width: 100%;
-    }
-    .gender-select {
-      width: 180px;
-      padding: 20px 0 10px;
-      display: flex;
-      align-items: center;
-      justify-content: space-around;
-      .gender-item {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        align-items: center;
-        font-size: 14px;
-        color: #999;
-        cursor: pointer;
-        img {
-          border-radius: 50%;
-        }
-        span {
-          margin-top: 4px;
-        }
-        &.active {
-          img {
-            border: 1px solid #4b72f6;
-          }
-          span {
-            color: #4b72f6;
-          }
-        }
-      }
-    }
-    .link {
-      margin-top: 10px;
-    }
-    .confirm-btn {
-      min-width: 60%;
-      margin: 15px auto 0;
-      background: #4b72f6;
-    }
-    .confirm-input {
-      border-color: #dbe0ef;
-    }
-    .confirm-input-btn {
-      border-radius: 4px;
-    }
-    .answer-btn {
-      background: #f5f5f5;
-      border-radius: 4px;
-      border: 0;
-      display: block;
-      width: 100%;
-      padding: 8px 15px;
-      box-sizing: border-box;
-      position: relative;
-      cursor: pointer;
-      &:before {
-        content: "";
-        background: #4b72f6;
-        width: 4px;
-        height: 4px;
-        display: inline-block;
-        vertical-align: middle;
-        border-radius: 50%;
-        position: absolute;
-        left: 5px;
-        top: 50%;
-        margin-top: -2px;
-      }
-      &.active {
-        color: #4b72f6;
-        background: #edf2fe;
-      }
-    }
-  }
-  .cur-answer {
-    .dialogue-content {
-      border-top-left-radius: 10px;
-      border-top-right-radius: 0;
-      background: #4b72f6;
-      color: #fff;
-    }
-  }
-  .full-btn {
-    display: block;
-    background: #4b72f6;
-    border: 0;
-    color: #fff;
-    text-shadow: 1px 1px 1px #643d066c;
-    font-size: 16px;
-    letter-spacing: 2px;
-    cursor: pointer;
-    border-radius: 4px;
-    height: 40px;
-    line-height: 40px;
-    margin-top: 20px;
-  }
-}
-</style>

+ 0 - 1284
src/views/healthManagement/components/questionItem.vue

@@ -1,1284 +0,0 @@
-<template>
-  <div
-    :style="{
-      'padding-top':
-        [QUESTION_TYPE_CHECKBOX, QUESTION_TYPE_RATING].includes(item.type) &&
-        (props.child || !item.isAnswered)
-          ? '25px'
-          : '',
-      'min-width': [
-        QUESTION_TYPE_RADIO,
-        QUESTION_TYPE_CHECKBOX,
-        QUESTION_TYPE_RATING
-      ].includes(item.type)
-        ? '200px'
-        : ''
-    }"
-  >
-    <p v-if="item.type !== QUESTION_TYPE_TEXT" class="survey-title">
-      <span class="text-red-500" v-if="item.config.required">*</span>
-      {{ item.attr && item.attr.includes("target") ? "" : item.number }}
-      {{ item.title }}
-    </p>
-    <div v-else-if="item.isHtml" class="survey-title" v-html="item.title" />
-    <p v-else class="survey-title">{{ item.title }}</p>
-    <!-- 临时选项 -->
-    <template v-if="item.type === QUESTION_TYPE_TEMP_CHECK">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-        <template v-if="props.child">
-          <transition name="fade">
-            <div class="text-right pt-2">
-              <van-button
-                color="#4B72F6"
-                class="confirm-input-btn"
-                @click="check(item, true)"
-                >是</van-button
-              >
-
-              <van-button class="confirm-input-btn" @click="check(item, false)"
-                >否</van-button
-              >
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 单选 -->
-    <template v-else-if="item.type === QUESTION_TYPE_RADIO">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <div
-                v-if="
-                  item.title.includes('性别') &&
-                  /男|女/.test(item.choices.map(v => v.label).join(''))
-                "
-                class="gender-select"
-              >
-                <div v-for="(sub, idx) in item.choices" :key="idx">
-                  <div
-                    v-if="!props.hideList.includes(sub.attr)"
-                    :data-topic="item.attr"
-                    class="gender-item"
-                    :class="{
-                      active: item.value === idx
-                    }"
-                    :disabled="!props.child && item.isAnswered"
-                    :value="idx"
-                    @click="reply(item, sub, idx)"
-                  >
-                    <Image
-                      v-if="sub.label.includes('男')"
-                      :src="iconMan"
-                      alt=""
-                      mode="cover"
-                    />
-                    <Image
-                      v-if="sub.label.includes('女')"
-                      :src="iconWoman"
-                      alt=""
-                      mode="cover"
-                    />
-                    <span>{{ sub.label }}</span>
-                  </div>
-                </div>
-              </div>
-              <template v-else>
-                <div v-for="(sub, idx) in item.choices" :key="idx">
-                  <div
-                    v-if="!props.hideList.includes(sub.attr)"
-                    :data-topic="item.attr"
-                    class="sub-title mt-4"
-                  >
-                    <div
-                      class="text-left answer-btn"
-                      :class="{
-                        active: item.value === idx
-                      }"
-                      :disabled="!props.child && item.isAnswered"
-                      :value="idx"
-                      @click="reply(item, sub, idx, true)"
-                    >
-                      {{ sub.label }}
-                    </div>
-                  </div>
-                  <el-input
-                    v-if="sub.isInput && item.value === idx"
-                    v-model="sub.extra"
-                    type="textarea"
-                    autosize
-                    :autocomplete="false"
-                    class="border border-solid border-gray-200 rounded px-2 py-1 outline-none border-radius-5 mt-2"
-                    :placeholder="sub.inputPlaceholder || '请输入'"
-                  />
-                </div>
-
-                <div>
-                  <!-- <div
-                    v-for="(sub, idx) in item.choices"
-                    :key="idx"
-                    class="sub-title margin-top-5 hide"
-                    @click.stop="reply(item, sub, idx, true)"
-                  >
-                    <el-radio-group v-model="item.rawValue">
-                      <el-radio :label="sub.label">
-                        <span class="cursor-copy">{{ sub.label }}</span>
-                      </el-radio>
-                    </el-radio-group>
-
-                    <el-input
-                      v-if="sub.isInput && item.rawValue === idx"
-                      v-model="sub.extra"
-                      type="textarea"
-                      autosize
-                      :autocomplete="false"
-                      :placeholder="sub.inputPlaceholder || '请输入'"
-                    />
-                  </div> -->
-                </div>
-              </template>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 多选 -->
-    <template v-else-if="item.type === QUESTION_TYPE_CHECKBOX">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <span class="survey-tag">可多选</span>
-              <div v-for="(sub, idx) in item.choices" :key="idx">
-                <div
-                  v-if="!props.hideList.includes(sub.attr)"
-                  :key="idx"
-                  :data-topic="item.attr"
-                  class="mt-4 sub-title"
-                >
-                  <div
-                    class="text-left answer-btn"
-                    :class="{
-                      active: item.value && item.value?.includes(idx)
-                    }"
-                    :disabled="!props.child && item.isAnswered"
-                    :value="idx"
-                    @click="reply(item, sub, idx, true)"
-                  >
-                    {{ sub.label }}
-                  </div>
-                  <input
-                    v-if="sub.isInput && item.value?.includes(idx)"
-                    v-model="sub.extra"
-                    type="textarea"
-                    autosize
-                    :autocomplete="false"
-                    class="border border-solid border-gray-200 rounded px-2 py-1 outline-none border-radius-5 mt-2"
-                    :placeholder="sub.inputPlaceholder || '请输入'"
-                  />
-                </div>
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 单行文本题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_INPUT">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <!-- v-if="item.value !== null && item.value !== undefined" -->
-              <div class="mb-5 mt-2 flex items-center">
-                <el-input
-                  v-model="item.value"
-                  placeholder="请输入"
-                  autosize
-                  autocomplete="off"
-                  @keyup.enter="reply(item)"
-                />
-                <!-- <input
-                  :type="inputType(item.config)"
-                  v-model="item.value"
-                  placeholder="请输入"
-                  class="mr-2 w-40 confirm-input"
-                  :style="{
-                    width: !props.child ? '150px' : '100%'
-                  }"
-                  :disabled="!props.child && item.isAnswered"
-                  :type="inputType(item.config?.rule)"
-                  @keyup.enter="reply(item)"
-                  @blur="inputBlur()"
-                /> -->
-                <!-- <el-button
-                  v-if="!props.child"
-                  :disabled="item.isAnswered"
-                  color="#4B72F6"
-                  class="confirm-input-btn ml-2"
-                  @click="reply(item)"
-                  size="mini"
-                  >确定</el-button
-                > -->
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 多行文本题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_TEXTAREA">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <!-- v-if="item.value !== null && item.value !== undefined" -->
-              <div class="mb-5 mt-2 flex items-center">
-                <!-- <textarea
-                  v-model="item.value"
-                  placeholder="请输入"
-                  autosize
-                  autocomplete="off"
-                  :style="{
-                    width: !props.child ? '150px' : '100%'
-                  }"
-                  class="mr-2 w-40 border border-solid border-gray-200 rounded px-2 py-1 outline-none"
-                /> -->
-                <el-input
-                  type="textarea"
-                  v-model="item.value"
-                  placeholder="请输入"
-                />
-                <!-- <input
-                  :type="inputType(item.config)"
-                  v-model="item.value"
-                  placeholder="请输入"
-                  class="mr-2 w-40 confirm-input"
-                  :style="{
-                    width: !props.child ? '150px' : '100%'
-                  }"
-                  :disabled="!props.child && item.isAnswered"
-                  :type="inputType(item.config?.rule)"
-                  @keyup.enter="reply(item)"
-                  @blur="inputBlur()"
-                /> -->
-                <!-- <el-button
-                  v-if="!props.child"
-                  :disabled="item.isAnswered"
-                  color="#4B72F6"
-                  class="confirm-input-btn ml-2"
-                  @click="reply(item)"
-                  size="mini"
-                  >确定</el-button
-                > -->
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 量表题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_SCALE">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div class="text-left padding-top-10 padding-bottom-10">
-              <div class="row pt-4">
-                <div class="flex">
-                  <div class="flex items-center flex-col">
-                    <span class="whitespace-nowrap mx-4">{{
-                      item.choices[0].label
-                    }}</span>
-                    <div>{{ item.min }}</div>
-                  </div>
-                  <el-slider
-                    v-model="item.value"
-                    :show-tooltip="true"
-                    :min="item.min"
-                    :max="item.max"
-                    :step="1"
-                  />
-                  <div class="flex items-center flex-col">
-                    <span class="whitespace-nowrap mx-4">{{
-                      item.choices[1].label
-                    }}</span>
-                    <div>{{ item.max }}</div>
-                  </div>
-                </div>
-              </div>
-            </div>
-            <!-- <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <div class="flex w-[60vw] items-center">
-                <div class="flex flex-col">
-                  <span class="text-sm text-gray-600 whitespace-nowrap">{{
-                    item.choices[0].label
-                  }}</span>
-                  <span class="text-xs text-gray-500">{{ item.min }}</span>
-                </div>
-                <div class="flex-1 px-4 mt-2">
-                  <van-slider
-                    v-model="item.value"
-                    :min="item.min"
-                    :max="item.max"
-                  >
-                    <template #button>
-                      <div
-                        class="w-7 h-7 rounded-full shadow border-2 border-solid border-[#4B72F6] bg-white text-[#4B72F6] text-sm p-2 flex justify-center items-center"
-                      >
-                        {{ item.value }}
-                      </div>
-                    </template>
-                  </van-slider>
-                </div>
-                <div class="flex flex-col text-right">
-                  <span class="text-sm text-gray-600 whitespace-nowrap">{{
-                    item.choices[1].label
-                  }}</span>
-                  <span class="text-xs text-gray-500">{{ item.max }}</span>
-                </div>
-              </div>
-              <div class="pt-4 flex justify-end">
-                <van-button
-                  v-if="!props.child"
-                  :disabled="item.isAnswered"
-                  color="#4B72F6"
-                  class="confirm-input-btn"
-                  @click="reply(item)"
-                  >确定</van-button
-                >
-              </div>
-            </div> -->
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 量表题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_RATING_SCALE">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <div class="row">
-                <div class="flex justify-between items-center mb-2">
-                  <span class="mr-5">{{ item.choices[0].label }}</span>
-                  <span class="ml-2">{{ item.choices[1].label }}</span>
-                </div>
-
-                <el-button
-                  v-for="(sub, idx) in item.rating"
-                  :key="idx"
-                  :disabled="!props.child && item.isAnswered"
-                  :style="{
-                    marginLeft: idx ? '-1px' : ''
-                  }"
-                  :type="item.value === sub ? 'primary' : 'default'"
-                  :value="idx"
-                  @click="reply(item, sub, idx)"
-                  >{{ sub }}</el-button
-                >
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 评分题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_RATING">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <span class="survey-tag">可多选</span>
-              <div v-for="(sub, idx) in item.choices" :key="idx">
-                <div
-                  v-if="!props.hideList.includes(sub.attr)"
-                  :key="idx"
-                  :data-topic="item.attr"
-                  class="mt-4 sub-title"
-                >
-                  <template v-if="item.isMultiple">
-                    <div
-                      class="text-left answer-btn"
-                      :class="{
-                        active: item.value && item.value.includes(idx)
-                      }"
-                      :disabled="!props.child && item.isAnswered"
-                      :value="idx"
-                      @click="reply(item, sub, idx, true)"
-                    >
-                      {{ sub.label }}
-                    </div>
-                  </template>
-                  <template v-else>
-                    <div
-                      class="text-left answer-btn"
-                      :class="{
-                        active: item.value && item.value.includes(idx)
-                      }"
-                      :disabled="!props.child && item.isAnswered"
-                      :value="idx"
-                      @click="reply(item, sub, idx)"
-                    >
-                      {{ sub.label }}
-                    </div>
-                  </template>
-                </div>
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 时间题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_DATE">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <!-- :label="item.title"  -->
-              <!-- <EditDatetimeCell
-                v-model:value="item.value"
-                :type="item.config.type"
-                :placeholder="item?.config?.desc"
-              /> -->
-              <div class="flex items-center">
-                <el-date-picker
-                  v-model="item.value"
-                  type="date"
-                  :placeholder="item.remark || '选择时间'"
-                />
-                <div class="text-right">
-                  <!-- <el-button
-                    v-if="!props.child"
-                    :disabled="!props.child && item.isAnswered"
-                    color="#4B72F6"
-                    class="confirm-input-btn ml-2"
-                    @click="reply(item)"
-                    size="mini"
-                    >确定</el-button
-                  > -->
-                </div>
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 矩阵矢量题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_MATRIX">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <div class="survey-matrix-container">
-                <table class="survey-matrix">
-                  <tr>
-                    <th />
-                    <th
-                      v-for="(subTh, subThIdx) in item.columns"
-                      :key="subThIdx"
-                    >
-                      {{ subTh.label }}
-                    </th>
-                  </tr>
-                  <tr v-for="(row, rowIdx) in item.rows" :key="rowIdx">
-                    <td>{{ row.label }}</td>
-                    <td
-                      v-for="(col, colIdx) in item.columns"
-                      :key="colIdx"
-                      @click="checkMatrix(rowIdx, colIdx)"
-                    >
-                      <div class="flex items-center justify-center">
-                        <!-- <Icon
-                          :name="
-                            item.matrix[rowIdx][colIdx] ? 'checked' : 'circle'
-                          "
-                          color="#4B72F6"
-                          size="20"
-                        /> -->
-                        <el-icon
-                          v-if="item.matrix[rowIdx][colIdx]"
-                          style="color: #67c23a; font-size: 20px"
-                          class="mr-2"
-                          ><SuccessFilled
-                        /></el-icon>
-                        <el-icon v-else style="font-size: 20px" class="mr-2"
-                          ><CircleCheck
-                        /></el-icon>
-                        <!-- <el-checkbox
-                          :checked="
-                            (item.value || []).includes(
-                              `${item.rows[$index]?.label}${item.columns[colIdx]?.label}`
-                            )
-                          "
-                        /> -->
-                      </div>
-                    </td>
-                  </tr>
-                </table>
-              </div>
-              <!-- <div class="pt-4 text-right">
-                <van-button
-                  v-if="!props.child"
-                  :disabled="!props.child && item.isAnswered"
-                  color="#4B72F6"
-                  class="confirm-input-btn"
-                  @click="reply(item)"
-                >确定</van-button>
-              </div> -->
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <template v-else-if="item.type === QUESTION_TYPE_GROUP">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <!-- <p class="survey-desc">{{ item.remark || item.config.desc }}</p> -->
-              <div v-for="(sub, subIdx) in item.children" :key="subIdx">
-                <QuestionItem
-                  v-model:info="item.children[subIdx]"
-                  :child="true"
-                  class="w-100"
-                  @skip="skip"
-                  @back="back"
-                  @check-matrix="checkMatrix"
-                  @reply="reply"
-                />
-              </div>
-
-              <div class="pt-4 text-right">
-                <!-- <van-button
-                  :disabled="!props.child && item.isAnswered"
-                  color="#4B72F6"
-                  class="confirm-input-btn"
-                  @click="reply(item)"
-                  >确定</van-button
-                > -->
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 组合题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_COMBINATION">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <transition name="fade">
-            <div>
-              <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
-              <div
-                v-for="(sub, subIdx) in item.children"
-                :key="subIdx"
-                class="pt-4"
-              >
-                <QuestionItem
-                  :info="sub"
-                  :child="true"
-                  class="w-100"
-                  @skip="skip"
-                  @back="back"
-                />
-              </div>
-              <div class="pt-4 text-right">
-                <!-- <van-button
-                  :disabled="!props.child && item.isAnswered"
-                  color="#4B72F6"
-                  class="confirm-input-btn"
-                  @click="reply(item)"
-                  >确定</van-button
-                > -->
-              </div>
-            </div>
-          </transition>
-        </template>
-      </div>
-    </template>
-    <!-- 下拉题 -->
-    <template v-else-if="item.type === QUESTION_TYPE_SELECT">
-      <!-- 常规显示 -->
-      <div class="text-left">
-        <template v-if="props.child || !item.isAnswered">
-          <div class="min-w-[40vw]">
-            <van-cell is-link @click="openSelect">
-              <template #title>
-                <span class="text-gray-600">{{
-                  item.value && item.value?.length
-                    ? item.value?.map(v => v.value).join()
-                    : "请选择"
-                }}</span>
-              </template>
-            </van-cell>
-          </div>
-        </template>
-      </div>
-      <van-popup v-model:show="selectVisible" position="bottom" teleport="body">
-        <div class="text-center p-4">{{ item.title }}</div>
-        <div v-if="selectChecked.length" class="p-4">
-          <p>已选择:</p>
-          <div
-            v-for="(checkItem, checkIdx) in selectChecked"
-            :key="checkIdx"
-            class="inline-flex items-center bg-gray-100 rounded-full text-gray-600 text-sm p-1 px-3 m-1"
-          >
-            <span>{{ checkItem.properties.name }}</span>
-
-            <van-icon
-              name="clear"
-              class="ml-2"
-              @click="selectChecked.splice(checkIdx, 1)"
-            />
-          </div>
-        </div>
-        <div class="flex p-4">
-          <input
-            type="text"
-            v-model="selectKeyword"
-            class="border border-gray-200 border-r-0 rounded-l px-4"
-            placeholder="请输入后搜索"
-            @keyup.enter.native="searchSelectOptions"
-          />
-          <van-button
-            type="primary"
-            class="rounded-l-none"
-            @click="searchSelectOptions"
-            >搜索</van-button
-          >
-        </div>
-        <div v-if="item.config.isAppendNull" class="px-4 text-sm text-gray-500">
-          未搜索到?可填入后直接保存
-        </div>
-        <div class="h-[50vh] overflow-y-auto">
-          <div
-            v-for="(selectItem, selectIndex) in selectOptions"
-            :key="selectIndex"
-            class="border-0 border-b border-gray-100 py-2 px-4 flex justify-between"
-            :class="{
-              'text-blue-700': selectChecked.find(v => v.id == selectItem.id)
-            }"
-            @click="selectItemChange(selectItem)"
-          >
-            <span>{{ selectItem.properties?.name }}</span>
-            <van-icon
-              v-if="selectChecked.find(v => v.id == selectItem.id)"
-              name="success"
-            />
-          </div>
-          <van-empty v-if="!selectOptions.length"
-            ><span class="text-gray-600 text-sm">暂无数据</span></van-empty
-          >
-        </div>
-        <div class="flex w-full">
-          <van-button
-            class="flex-1 rounded-none border-0"
-            @click="selectVisible = false"
-            >取消</van-button
-          >
-          <van-button
-            type="primary"
-            class="flex-1 rounded-none border-0"
-            @click="saveSelect"
-            >保存</van-button
-          >
-        </div>
-      </van-popup>
-    </template>
-    <!-- <template v-if="!props.child">
-      <p
-        v-if="!item.isAnswered && !item.config?.required"
-        class="link text-center"
-        @click="skip(item)"
-      >
-        跳过该题
-      </p>
-      <div
-        v-if="
-          !item.isAnswered &&
-          (item.isMultiple ||
-            item.type === QUESTION_TYPE_MATRIX ||
-            (item.choices?.length && item.choices.find(v => v.isInput)))
-        "
-        class="flex items-center justify-center"
-      >
-        <van-button
-          type="primary"
-          round
-          class="text-center confirm-btn"
-          size="small"
-          @click="reply(item, null, undefined)"
-          >确定<span v-if="item.value?.length"
-            >({{ item.value.length }}个)</span
-          >
-        </van-button>
-      </div>
-      <p
-        v-if="!item.isAnswered && repeatAnswer"
-        class="link text-center"
-        @click="back(item)"
-      >
-        重答该题
-      </p>
-    </template> -->
-  </div>
-</template>
-
-<script setup>
-import { defineProps, defineEmits, computed, ref, reactive } from "vue";
-// import { Button, Icon, showNotify, Field, Image, Popup } from "vant";
-import { CircleCheck, SuccessFilled } from "@element-plus/icons-vue";
-import { formatAge, request } from "@/utils";
-// import EditDatetimeCell from "@/components/EditDatetimeCell.vue";
-import QuestionItem from "./questionItem.vue";
-import iconMan from "@/assets/icon-man.png";
-import iconWoman from "@/assets/icon-woman.png";
-import { ElMessage } from "element-plus";
-const QUESTION_TYPE_TEMP_CHECK = "temp_check"; // 单选 => Q1A1
-const QUESTION_TYPE_INPUT = "input"; // 输入 => Q1
-const QUESTION_TYPE_TEXTAREA = "textarea"; // 输入 => Q1
-const QUESTION_TYPE_TEXT = "text"; // 输入 => Q1
-const QUESTION_TYPE_CHECKBOX = "checkbox"; // 多选 => Q1A1
-const QUESTION_TYPE_RADIO = "radio"; // 单选 => Q1A1
-const QUESTION_TYPE_SCALE = "scale"; // 量表(一排的radio选择指定) => Q1
-const QUESTION_TYPE_RATING_SCALE = "rating_scale"; // 量表(一排的radio选择指定) => Q1
-const QUESTION_TYPE_RATING = "rating"; // 评分题(选项后面有分值) => Q1A1
-const QUESTION_TYPE_DATE = "date"; // 时间题
-const QUESTION_TYPE_MATRIX = "matrix_checkbox"; // 矢量题
-const QUESTION_TYPE_COMBINATION = "combination"; // 组合题
-const QUESTION_TYPE_GROUP = "group"; // 组合题
-const QUESTION_TYPE_SELECT = "select"; // 组合题
-const emits = defineEmits(["update:info", "skip", "back", "check", "reply"]);
-const props = defineProps({
-  info: {
-    type: Object,
-    default: () => {}
-  },
-  hideList: {
-    type: Array,
-    default: () => []
-  },
-  repeatAnswer: {
-    type: Boolean,
-    default: false
-  },
-  child: {
-    type: Boolean,
-    default: false
-  }
-});
-// console.log(props.info);
-
-const item = computed({
-  get() {
-    return props.info;
-  },
-  set(value) {
-    emits("update:info", value);
-  }
-});
-
-const init = () => {
-  if (item.value.type === QUESTION_TYPE_MATRIX) {
-    console.log("测试", item.value);
-
-    item.value.matrix = Array(item.value.rows.length)
-      .fill(0)
-      .map(() => Array(item.value.columns.length).fill(false))
-      .map((rows, rowIdx) => {
-        rows = rows.map((col, colIdx) => {
-          if (item.value.value && Array.isArray(item.value.value)) {
-            return item.value.value.includes(
-              item.value.rows[rowIdx].label + item.value.columns[colIdx].label
-            );
-          }
-          return col;
-        });
-        return rows;
-      });
-  }
-};
-
-const replyLock = ref(false);
-
-const inputType = config => {
-  if (config?.regexRule) {
-    const { dataType } = config.regexRule;
-    switch (dataType) {
-      case "numeric":
-        return "number";
-      default:
-        return "text";
-    }
-  } else {
-    switch (config.rule) {
-      case "number":
-        return config.rule;
-      case "phone":
-        return "tel";
-      default:
-        return "text";
-    }
-  }
-};
-
-// 矩阵题选择
-const checkMatrix = (rowIdx, colIdx) => {
-  const curState = item.value.matrix[rowIdx][colIdx];
-  const isMultiple = item.value.isMultiple;
-  const mutuallyExclusive = item.value.columns[colIdx].mutuallyExclusive;
-  // 单选
-  if (!isMultiple) {
-    item.value.matrix[rowIdx].forEach((v, k) => {
-      item.value.matrix[rowIdx][k] = k === colIdx ? !curState : false;
-    });
-  } else {
-    // 多选
-    // 该列有互斥
-    if (mutuallyExclusive) {
-      if (curState) {
-        item.value.matrix[rowIdx][colIdx] = !curState;
-      } else {
-        item.value.matrix[rowIdx].forEach((v, k) => {
-          item.value.matrix[rowIdx][k] = k === colIdx;
-        });
-      }
-    } else {
-      item.value.matrix[rowIdx].forEach((v, k) => {
-        if (item.value.columns[k].mutuallyExclusive) {
-          item.value.matrix[rowIdx][k] = false;
-        }
-      });
-      item.value.matrix[rowIdx][colIdx] = !item.value.matrix[rowIdx][colIdx];
-    }
-  }
-};
-const skip = item => {
-  item.value = null;
-  emits("skip", item);
-};
-const back = item => {
-  emits("back", item);
-};
-const check = (item, flag) => {
-  emits("check", item, flag);
-};
-
-const regexRuleCheck = item => {
-  if (item.config?.regexRule) {
-    const { regexRule } = item.config;
-    const { name, data, dataType, dataTotal } = regexRule;
-    const { valueList, total } = data;
-    const value = item.value;
-
-    if (dataTotal === "required") {
-      if (!value && value !== 0) return "请输入内容";
-      return "";
-    }
-    console.log("value", dataType, value);
-
-    switch (dataType) {
-      case "specific":
-        if (valueList.includes(value)) {
-          return "";
-        }
-        return `仅能输入${valueList.join("、")}`;
-      case "numeric":
-        if (isNaN(value)) {
-          return "请输入数字";
-        }
-        if (total.min && value <= total.min) {
-          return `正确的数字区间为${total.min}~${total.max}`;
-        }
-        if (total.max && value >= total.max) {
-          return `正确的数字区间为${total.min}~${total.max}`;
-        }
-        return "";
-      case "string":
-        if (total.min && value.length <= total.min) {
-          return `请输入至少${total.min}位`;
-        }
-        if (total.max && value.length >= total.max) {
-          return `请输入最多${total.max}位`;
-        }
-        return "";
-      default:
-        break;
-    }
-    return "";
-  }
-  return "";
-};
-const checkReply = item => {
-  if (regexRuleCheck(item)) {
-    ElMessage.error(regexRuleCheck(item));
-    // showNotify({ type: "danger", message: regexRuleCheck(item) });
-    replyLock.value = false;
-    return false;
-  }
-  if (item.type === QUESTION_TYPE_MATRIX) {
-    return true;
-  } else if (item["choices"]?.length) {
-    if (
-      (!item.value && item.value !== 0) ||
-      (Array.isArray(item.value) && !item.value.length)
-    ) {
-      // showNotify({ type: "danger", message: "请选择" });
-      ElMessage.error("请选择");
-      replyLock.value = false;
-      return false;
-    }
-  } else {
-    if (!item.value && item.value !== 0) {
-      // showNotify(item.value)
-      ElMessage.error(
-        `请${item.type === QUESTION_TYPE_DATE ? "选择" : "填写正确内容"}后提交`
-      );
-      // showNotify({
-      //   type: "danger",
-      //   message: `请${
-      //     item.type === QUESTION_TYPE_DATE ? "选择" : "填写正确内容"
-      //   }后提交`
-      // });
-      replyLock.value = false;
-      return false;
-    }
-  }
-  return true;
-};
-
-const reply = (item, sub, idx, skip) => {
-  console.log("触发reply", replyLock.value, item);
-  if (replyLock.value) return;
-  console.log("执行reply", item, sub);
-
-  replyLock.value = true;
-  let text = "";
-  if (
-    item.type === QUESTION_TYPE_INPUT ||
-    item.type === QUESTION_TYPE_TEXTAREA
-  ) {
-    // if (!item.value && item.value !== 0) {
-    //   showNotify({ type: 'danger', message: '请输入内容后提交' })
-    //   replyLock.value = false
-    //   return
-    // }
-    if (!checkReply(item)) return;
-    if (item.config?.rule) {
-      let reg = null;
-      let errMsg = "";
-      switch (item.config?.rule) {
-        case "number":
-          reg = /^\d+(\d+|\.\d+)?$/;
-          errMsg = "请输入数字";
-          break;
-        case "phone":
-          reg = /^(?:(?:\+|00)86)?1\d{10}$/;
-          errMsg = "请输入手机号码";
-          break;
-      }
-      if (reg && !new RegExp(reg).test(item.value)) {
-        // showNotify({ type: "danger", message: errMsg });
-        ElMessage.error(errMsg);
-        replyLock.value = false;
-        return;
-      }
-    }
-    text = item.value;
-  } else if (item.type === QUESTION_TYPE_SCALE) {
-    text = item.value;
-  } else if (
-    item.type === QUESTION_TYPE_CHECKBOX ||
-    (item.type !== QUESTION_TYPE_MATRIX && item.isMultiple)
-  ) {
-    if (skip) {
-      // let temp = [] as Array<number>
-      if (typeof item.value === "string" || (!item.value && item.value !== 0)) {
-        item.value = [idx];
-      } else {
-        if (sub?.mutuallyExclusive) {
-          item.value = [idx];
-        } else {
-          item.value = item.value.filter(
-            v => !item.choices[v]?.mutuallyExclusive
-          );
-
-          if (item.value.includes(idx)) {
-            item.value.splice(item.value.indexOf(idx), 1);
-          } else {
-            item.value = [...new Set([...item.value, idx])];
-          }
-        }
-      }
-
-      replyLock.value = false;
-      return;
-    } else {
-      if (item.isMultiple) {
-        // if (!item.value || (Array.isArray(item.value) && !item.value.length)) {
-        //   showNotify({ type: 'danger', message: '请选择' })
-        //   replyLock.value = false
-        //   return
-        // }
-        if (!checkReply(item)) return;
-        if (Array.isArray(item.value)) {
-          text = [];
-          item.value.map(v => {
-            text.push(item.choices[v].label);
-          });
-          text = text.join();
-        }
-      } else {
-        text = idx;
-      }
-      console.log(item.title);
-      console.log(item.value);
-    }
-  } else if (item.choices?.length && item.choices.find(v => v.isInput)) {
-    if (skip) {
-      const _sub = item.choices[idx];
-      item.value = idx;
-      text = _sub.isInput ? _sub.extra : _sub.label;
-      console.log(idx, _sub);
-      replyLock.value = false;
-      // return;
-    } else {
-      const _sub = item.choices[item.value];
-      text = _sub.isInput ? _sub.extra || _sub.label : _sub.label;
-    }
-  } else if (
-    item.type === QUESTION_TYPE_COMBINATION ||
-    item.type === QUESTION_TYPE_GROUP
-  ) {
-    console.log("QUESTION_TYPE_COMBINATION");
-    console.log("组合题value: ");
-    const val = [];
-    const t = [];
-    for (const child of item.children) {
-      if (!checkReply(child)) return;
-      if (child.type === QUESTION_TYPE_MATRIX) {
-        const res = [];
-        child.matrix.forEach((cols, k1) => {
-          cols.forEach((c, k2) => {
-            c && res.push(child.rows[k1].label + "" + child.columns[k2].label);
-          });
-        });
-        if (res?.length) {
-          t.push(res.join(","));
-          val.push(res);
-        } else {
-          t.push("无");
-          val.push(["无"]);
-        }
-      } else if (child["choices"]?.length) {
-        t.push(
-          Array.isArray(child.value)
-            ? child.value.map(c => child["choices"][c]?.label).join(",")
-            : child["choices"][child.value]?.label
-        );
-        val.push(child.value);
-      } else {
-        t.push(child.value);
-        val.push(child.value);
-      }
-    }
-    // item.value = item.children.map((child) => {
-    //   if (child.type === QUESTION_TYPE_MATRIX) {
-    //     let res = []
-    //     child.matrix.forEach((cols: boolean[], k1: number) => {
-    //       cols.forEach((c: boolean, k2: number) => {
-    //         c && res.push(child.rows[k1].label + '' + child.columns[k2].label)
-    //       })
-    //     })
-    //     if (res?.length) {
-    //       t.push(res.join(','))
-    //       return res
-    //     } else {
-    //       t.push('无')
-    //       return ['无']
-    //     }
-    //   } else if (child['choices']?.length) {
-    //     t.push(Array.isArray(child.value) ? child.value.map((c) => child['choices'][c]?.label).join(',') : child['choices'][child.value]?.label)
-    //   } else {
-    //     t.push(child.value)
-    //     return child.value
-    //   }
-    //   return child.value
-    // })
-    text = t.join(",");
-    console.log(item.value, text);
-
-    console.log("==========");
-  } else if (item.type === QUESTION_TYPE_RATING_SCALE) {
-    item.value = sub;
-    text = sub;
-  } else if (item.type === QUESTION_TYPE_DATE) {
-    // if (!item.value && item.value !== 0) {
-    //   showNotify({ type: 'danger', message: '请选择后提交' })
-    //   replyLock.value = false
-    //   return
-    // }
-    if (!checkReply(item)) return;
-    // if (item.config?.rule && item.config?.rule === 'age') {
-    //   item.value = formatAge(item.value)
-    // } else {
-    // }
-    item.value = item.value || "";
-    text = item.config?.rule === "age" ? formatAge(item.value) : item.value;
-  } else if (item.type === QUESTION_TYPE_MATRIX) {
-    const res = [];
-    console.log(`回答矩阵题-----1`);
-    console.log(item.matrix, item.rows, item.columns);
-
-    item.matrix.forEach((cols, k1) => {
-      cols.forEach((c, k2) => {
-        c && res.push(item.rows[k1].label + "" + item.columns[k2].label);
-      });
-    });
-    item.value = res && res.length ? res : ["无"];
-    text = res && res.length ? res.join(",") : "无";
-    console.log(`回答矩阵题`);
-    console.log(res);
-  } else if (item.type === QUESTION_TYPE_SELECT) {
-    item.value = selectChecked.value.map(v => {
-      return {
-        key: v.id || "",
-        value: v.properties.name
-      };
-    });
-    text = selectChecked.value.map(v => v.properties.name).join() || "无";
-  } else {
-    console.log(`执行到else来了 ${item.type}`);
-    item.value = idx;
-    text = item.choices[idx].label;
-  }
-  // item.isAnswered = true;
-  replyLock.value = false;
-  emits("reply", item, text);
-};
-// init();
-
-const selectVisible = ref(false);
-const selectKeyword = ref();
-const selectOptions = ref([]);
-const selectChecked = ref([]);
-const selectItemChange = selectItem => {
-  if (selectChecked.value.find(v => v.id == selectItem.id)) {
-    selectChecked.value.splice(
-      selectChecked.value.findIndex(v => v == selectItem.id),
-      1
-    );
-  } else {
-    if (item.value.config.isMultiple) {
-      selectChecked.value.push(selectItem);
-    } else {
-      selectChecked.value = [selectItem];
-    }
-  }
-};
-const searchSelectOptions = async () => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 999,
-      tag: item.value.config.sourceTag,
-      name: selectKeyword.value
-    }
-  });
-  selectOptions.value = data.list;
-};
-const saveSelect = () => {
-  if (
-    !selectChecked.value.length &&
-    selectKeyword.value &&
-    item.value.config.isAppendNull
-  ) {
-    selectChecked.value.push({
-      id: "",
-      properties: {
-        name: selectKeyword.value
-      }
-    });
-  }
-  reply(item.value);
-  selectVisible.value = false;
-  selectOptions.value = [];
-  selectKeyword.value = "";
-};
-const openSelect = () => {
-  if (item.value.value) {
-    selectChecked.value = item.value.value.map(v => {
-      return {
-        id: v.key,
-        properties: {
-          name: v.value
-        }
-      };
-    });
-  }
-  selectVisible.value = true;
-};
-</script>
-
-<style lang="scss">
-.survey-matrix-container {
-  overflow-x: auto;
-  padding: 10px 0;
-  .survey-matrix {
-    font-size: 12px;
-    border-collapse: collapse;
-    margin: 0 auto;
-    min-width: 100%;
-    th,
-    td {
-      border: 1px solid #ccc;
-      padding: 10px;
-      text-align: center;
-    }
-    th {
-      white-space: nowrap;
-    }
-    tr {
-      td:first-of-type {
-        font-weight: blod;
-        white-space: nowrap;
-      }
-    }
-  }
-}
-.confirm-input-btn {
-  cursor: pointer;
-  height: 34px;
-  &:not(:last-of-type) {
-    margin-right: 10px;
-  }
-}
-
-.link {
-  color: #4b72f6;
-}
-</style>

+ 0 - 1029
src/views/healthManagement/evaluate.vue

@@ -1,1029 +0,0 @@
-<template>
-  <div>
-    <AutoCompleteStep
-      v-if="isVisibleAnalyze && !stepInit"
-      class="bg-white rounded"
-      @confirm="stepConfirm"
-    />
-    <template v-if="stepInit">
-      <template v-if="needQA">
-        <DiseaseQA
-          :userId="route.query.archivesId"
-          :diseaseId="route.query.illnessId"
-          @confirm="diseaseQAConfirm"
-        />
-      </template>
-      <div v-show="!needQA">
-        <div class="grid grid-cols-2 gap-2">
-          <div class="bg-white border border-gray-100">
-            <div
-              class="flex items-center justify-between p-3 shadow-sm bg-white mb-3"
-            >
-              <div>
-                <h3 class="" v-if="illName">当前评估疾病: {{ illName }}</h3>
-              </div>
-              <div>
-                <!-- @click="" -->
-                <el-button
-                  v-if="isVisibleAnalyze"
-                  type="primary"
-                  plain
-                  @click="
-                    stepInit = false;
-                    getDiseaseAnalysis();
-                  "
-                  >智能分析</el-button
-                >
-                <el-button
-                  type="primary"
-                  plain
-                  @click="handleSave"
-                  v-if="!state.detail.status || !pageType || isEvaluateTime"
-                  >保存</el-button
-                >
-                <el-button type="danger" plain @click="handleQuit"
-                  >退出</el-button
-                >
-
-                <el-button type="primary" plain @click="handleBacklog"
-                  >待办事项管理</el-button
-                >
-              </div>
-            </div>
-            <div v-if="!state.detail.status">
-              <div v-if="isEvaluateTime || pageType !== 'evaluate'">
-                <el-scrollbar style="height: calc(100vh - 220px)">
-                  <div class="p-3">
-                    <div v-if="pageType != 'edit'">
-                      <el-card class="mb-2">
-                        <template #header>
-                          <h3>评估时间范围</h3>
-                        </template>
-                        <div v-if="isEvaluate">
-                          {{ state?.detail?.createdAt?.split(" ")[0] }} 至
-                          {{
-                            state?.detail?.nextTime?.split(" ")[0] ||
-                            moment().format("YYYY-MM-DD")
-                          }}
-                        </div>
-                        <div v-else>
-                          <el-text
-                            >-- 至
-                            {{ moment().format("YYYY-MM-DD") }} 期间</el-text
-                          >
-                        </div>
-                      </el-card>
-                      <el-card v-if="isEvaluate" class="mb-2">
-                        <template #header>
-                          <div class="flex items-center justify-between">
-                            <el-row class="flex items-center">
-                              <el-tag class="mr-2" v-if="state.lastLevelName">
-                                {{ formatLevel(state.lastLevelName) }}
-                              </el-tag>
-                              <el-tag class="mr-2" v-else>{{
-                                manageLevel[state.lastLevel]?.anotherName
-                              }}</el-tag>
-                              <h3>设定的管理目标</h3>
-                            </el-row>
-                            <div class="text-right">
-                              <el-button
-                                type="primary"
-                                link
-                                @click="handleWatchSuggest"
-                                >查看健康建议</el-button
-                              >
-                            </div>
-                          </div>
-                        </template>
-                        <div>
-                          {{ state.detail?.target }}
-                        </div>
-                      </el-card>
-                      <el-card v-if="isEvaluate" class="mb-2">
-                        <template #header>
-                          <div class="flex items-center justify-between">
-                            <el-row class="flex items-center">
-                              <h3>期间该用户待办事项完成情况</h3>
-                            </el-row>
-                            <div class="text-right">
-                              <el-text>
-                                统计日期:
-                                {{ state?.detail?.createdAt?.split(" ")[0] }} 至
-                                {{ moment().format("YYYY-MM-DD") }}
-                              </el-text>
-                            </div>
-                          </div>
-                        </template>
-                        <div>
-                          <div
-                            v-for="(backlog, index) in state.backlogItemList"
-                            :key="index"
-                          >
-                            <div v-for="it in backlog.checkItems" :key="it.id">
-                              <el-text :tag="it.done ? 'del' : 'span'">
-                                <el-text>{{ backlog.date }}</el-text>
-                                <el-text class="ml-2">{{ it.content }}</el-text>
-                              </el-text>
-                            </div>
-                          </div>
-                        </div>
-                      </el-card>
-                      <evaluate-card shadow="always">
-                        <template #header>
-                          <div class="flex justify-between">
-                            <h3>健康状况评估:</h3>
-                            <el-button
-                              v-if="
-                                (state.analyzeDetail?.tools || []).find(
-                                  v => !v.toolType
-                                )
-                              "
-                              type="primary"
-                              plain
-                              @click="changeQAView"
-                              >{{
-                                Array.isArray(state.analyzeDetail?.tools)
-                                  ? `${
-                                      state.analyzeDetail?.tools.find(
-                                        v => !v.toolType
-                                      )?.toolName
-                                    }`
-                                  : "评估"
-                              }}</el-button
-                            >
-                          </div>
-                        </template>
-                        <div>
-                          <el-text bold size="large" tag="b"
-                            >现存主要问题:</el-text
-                          >
-                          <div class="flex mt-4">
-                            <el-input
-                              v-model="state.problem"
-                              placeholder="(选填)请输入现存主要问题,如:xx指标异常,吸烟等"
-                              clearable
-                            />
-                            <el-button
-                              type="primary"
-                              class="ml-2"
-                              @click="handleSaveIllness"
-                              >确认</el-button
-                            >
-                          </div>
-                          <div>
-                            <el-tag
-                              class="mr-2 mt-4"
-                              closable
-                              @close="handleCloseTag(index)"
-                              v-for="(item, index) in tagList"
-                              :key="index"
-                              >{{ item }}</el-tag
-                            >
-                          </div>
-                          <ComponentDiseaseAnalysis
-                            v-if="state.analyzeDetail?.mainProblem"
-                            :list="state.analyzeDetail?.mainProblem"
-                          />
-                        </div>
-                        <template #footer>
-                          <div>
-                            <el-form-item label="12" required>
-                              <template #label> 目前健康状况评价: </template>
-                              <el-select
-                                v-model="state.result"
-                                placeholder="请选择评价"
-                                filterable
-                              >
-                                <el-option
-                                  v-for="item in state.resultList"
-                                  :key="item.id"
-                                  :label="item.properties.name"
-                                  :value="item.id"
-                                />
-                              </el-select>
-                            </el-form-item>
-                            <ComponentDiseaseAnalysis
-                              v-if="state.analyzeDetail?.managEffect"
-                              :list="state.analyzeDetail?.managEffect"
-                            />
-                          </div>
-                        </template>
-                      </evaluate-card>
-                      <div
-                        class="bg-white mt-2 mb-2"
-                        style="width: 100%; border: 1px solid #fff"
-                      >
-                        <el-divider> 下个阶段管理设置 </el-divider>
-                      </div>
-                    </div>
-                    <!-- 下次评估时间 -->
-                    <div class="mt-2">
-                      <el-card>
-                        <template #header>
-                          <h3>下次评估时间:</h3>
-                        </template>
-                        <el-form-item label="下次评估间隔天数" required>
-                          <el-input
-                            type="number"
-                            placeholder="请输入天数"
-                            style="width: 100px"
-                            class="ml-2 mr-2"
-                            v-model="state.interval"
-                          />天,系统将在<span
-                            style="color: #f56c6c; font-weight: bold"
-                            >{{ formatTime(state.interval)?.label }}</span
-                          >
-                          提醒您对该用户进行下一次评估
-                        </el-form-item>
-                        <ComponentDiseaseAnalysis
-                          v-if="state.analyzeDetail?.nextAssessmentTime"
-                          :list="state.analyzeDetail?.nextAssessmentTime"
-                        />
-                        <div class="flex items-center flex-wrap" />
-                      </el-card>
-                    </div>
-                    <!-- 下次评估时间 -->
-                    <div class="mt-2">
-                      <el-card>
-                        <template #header>
-                          <el-form-item>
-                            <template #label>
-                              <h3 style="color: #333">
-                                下次评估前的预防/管理分组:
-                              </h3>
-                            </template>
-                          </el-form-item>
-                        </template>
-                        <div>
-                          <el-form-item label="预防/管理分组:" required>
-                            <el-select
-                              v-model="state.group"
-                              filterable
-                              placeholder="请选择"
-                            >
-                              <el-option
-                                v-for="item in state.groupList"
-                                :key="item.id"
-                                :label="item.name"
-                                :value="item.id"
-                              />
-                            </el-select>
-                          </el-form-item>
-                        </div>
-
-                        <ComponentDiseaseAnalysis
-                          v-if="state.analyzeDetail?.manageLevel"
-                          :list="state.analyzeDetail?.manageLevel"
-                        />
-                      </el-card>
-                    </div>
-                    <div class="mt-2">
-                      <el-card>
-                        <template #header>
-                          <el-form-item label="" required>
-                            <template #label>
-                              <h3>下次评估前的管理目标:</h3>
-                            </template>
-                          </el-form-item>
-                        </template>
-                        <div>
-                          <el-input
-                            v-model="state.target"
-                            :rows="4"
-                            type="textarea"
-                            placeholder="请输入管理目标"
-                          />
-                        </div>
-                        <ComponentDiseaseAnalysis
-                          v-if="state.analyzeDetail?.manageTargets"
-                          :list="state.analyzeDetail?.manageTargets"
-                        />
-                      </el-card>
-                    </div>
-                    <div class="mt-2">
-                      <el-card>
-                        <template #header>
-                          <div class="flex justify-between">
-                            <h3>下次评估前对该用户的个性化健康建议</h3>
-                            <div>
-                              <Auth value="healthManage:suggestion:view">
-                                <el-button
-                                  type="primary"
-                                  @click="visibleHealthAdviceLibrary = true"
-                                  >健康建议库</el-button
-                                >
-                              </Auth>
-                            </div>
-                          </div>
-                        </template>
-                        <div>
-                          <Editor v-model:value="state.advise" />
-                        </div>
-                      </el-card>
-                      <ComponentDiseaseAnalysis
-                        v-if="state.analyzeDetail?.personalHealthAdvice"
-                        :list="state.analyzeDetail?.personalHealthAdvice"
-                      />
-
-                      <el-card class="mt-2">
-                        <template #header>
-                          <div class="flex justify-between">
-                            <h3>下次评估前对该用户关键指标追踪</h3>
-                          </div>
-                        </template>
-                        <div class="flex flex-wrap">
-                          <div class="mr-2 mb-2">
-                            <el-tag
-                              closable
-                              size="large"
-                              v-for="(item, index) in metricInfo.list"
-                              :key="item.id"
-                              class="mr-2"
-                              @close="handleDeleteMetric(item, index)"
-                            >
-                              <div class="flex items-center">
-                                <div>{{ item.name }}</div>
-                                <el-divider direction="vertical" />
-                                <div>
-                                  <span
-                                    v-for="(value, key) in item.list"
-                                    :key="value.id"
-                                    >{{ value.name }}、</span
-                                  >
-                                </div>
-                              </div>
-                            </el-tag>
-                          </div>
-                          <div class="mb-2">
-                            <el-select
-                              v-model="metricInfo.projectId"
-                              filterable
-                              clearable
-                              collapse-tags
-                              placeholder="请选择检查项目"
-                              @change="searchRelateNodes"
-                            >
-                              <el-option
-                                v-for="(item, index) in metricInfo.projectList"
-                                :key="index"
-                                :label="item.name"
-                                :value="item.id"
-                              />
-                            </el-select>
-
-                            <el-select
-                              v-model="metricInfo.nodes"
-                              multiple
-                              filterable
-                              clearable
-                              collapse-tags
-                              :disabled="!metricInfo.projectId"
-                              placeholder="请选择内容"
-                            >
-                              <el-option
-                                v-for="(item, index) in metricInfo.nodeList"
-                                :key="index"
-                                :label="item.name"
-                                :value="item.id"
-                              />
-                            </el-select>
-                            <el-button
-                              type="primary"
-                              class="ml-2"
-                              @click="handleAddMetric"
-                              >添加</el-button
-                            >
-                          </div>
-                        </div>
-                      </el-card>
-                    </div>
-                  </div>
-                </el-scrollbar>
-              </div>
-
-              <div v-else>
-                <el-card shadow="never">
-                  <div class="text-center">
-                    <div style="font-size: 50px">
-                      <el-icon style="color: var(--el-color-primary)"
-                        ><Calendar
-                      /></el-icon>
-                    </div>
-                    <h2>未到设定的评估日期,无法评估</h2>
-                    <div class="flex items-center justify-center">
-                      <h2 class="mt-4 mb-4 mr-4">
-                        设置的评估日期:{{ evaluateDate }}
-                      </h2>
-                      <el-button type="primary"
-                        >还剩
-                        {{ timeDiffer(state.detail?.nextTime) }} 天</el-button
-                      >
-                    </div>
-                    <el-button
-                      type="primary"
-                      plain
-                      style="width: 300px; height: 40px"
-                      @click="handleSet"
-                      >修改设置</el-button
-                    >
-                  </div>
-                </el-card>
-              </div>
-            </div>
-            <div v-else>
-              <el-card>
-                <div class="text-center">
-                  <div style="font-size: 50px">
-                    <el-icon style="color: var(--el-color-primary)"
-                      ><VideoPause
-                    /></el-icon>
-                  </div>
-                  <h2 class="mb-3">该管理已暂停,无法评估</h2>
-                  <el-button
-                    type="primary"
-                    plain
-                    style="width: 300px; height: 40px"
-                    @click="handleRecover"
-                    >恢复管理</el-button
-                  >
-                </div>
-              </el-card>
-            </div>
-          </div>
-          <div class="">
-            <el-tabs
-              type="border-card"
-              v-model="state.currentTab"
-              @tab-click="handleChangeTab"
-            >
-              <el-tab-pane
-                :label="item.name"
-                :name="item.key"
-                v-for="item in menuList"
-                :key="item.key"
-                ref="historyRef"
-                lazy
-              >
-                <el-scrollbar style="height: calc(100vh - 204px)">
-                  <component
-                    v-if="item?.component"
-                    :is="item?.component"
-                    :list="state.historyData"
-                    :nodeId="route.query.illnessId"
-                  />
-                </el-scrollbar>
-              </el-tab-pane>
-            </el-tabs>
-          </div>
-        </div>
-      </div>
-    </template>
-    <ComponentDialogBacklog v-model:show="state.visibleBacklog" />
-    <ComponentDialogPreviewSuggest
-      v-model:show="state.visiblePreview"
-      :data="state.detail"
-    />
-
-    <DialogHealthAdviceLibrary
-      v-model:show="visibleHealthAdviceLibrary"
-      @onAdd="handleAddHealthAdviceLibrary"
-    />
-
-    <el-dialog v-model="QAHistoryDialogVisible">
-      <div class="bg-gray-50 rounded">
-        <div class="p-4">
-          <div class="mb-4">
-            <div class="text-gray-700 text-sm mb-2">分析结果:</div>
-            <div>{{ diseaseAnalysisResult.result }}</div>
-          </div>
-          <div v-if="diseaseAnalysisResult.reasons">
-            <div class="text-gray-700 text-sm mb-2">分析依据:</div>
-            <div
-              v-for="(item, index) in diseaseAnalysisResult.reasons"
-              :key="index"
-            >
-              {{ item }}
-            </div>
-          </div>
-          <div class="flex justify-end">
-            <el-button
-              type="warning"
-              plain
-              @click="
-                QAHistoryDialogVisible = false;
-                needQA = true;
-              "
-              >重新分析</el-button
-            >
-          </div>
-        </div>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import { computed, reactive, ref, defineAsyncComponent, nextTick } from "vue";
-import { Tools, Calendar, VideoPause } from "@element-plus/icons-vue";
-import { useRouter, useRoute } from "vue-router";
-import moment from "moment";
-const [route, router] = [useRoute(), useRouter()];
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-
-import EvaluateCard from "./components/EvaluateCard.vue";
-import ComponentDialogBacklog from "./components/DialogBacklog.vue";
-import ComponentDialogPreviewSuggest from "./components/DialogPreviewSuggest.vue";
-import DialogHealthAdviceLibrary from "@/views/healthRisk/components/DialogHealthAdviceLibrary.vue";
-import ComponentDiseaseAnalysis from "./components/DiseaseAnalysis.vue";
-import DiseaseQA from "./components/DiseaseQA.vue";
-import AutoCompleteStep from "./components/AutoCompleteStep.vue";
-import Editor from "@/components/Editor.vue";
-
-import { request, transformDataExpand, timeDiffer } from "@/utils";
-import { ElMessage, ElMessageBox } from "element-plus";
-import { manageLevel, formatLevel } from "@/enums/managementPlan";
-
-const currentArchiveId = computed(() => {
-  return useManageProjectStoreHook()?.currentArchiveId;
-});
-
-const stepInit = ref(false);
-const stepConfirm = () => {
-  stepInit.value = true;
-};
-
-const state = reactive({
-  problem: "",
-  level: "",
-  target: "",
-  advise: "",
-  visibleSet: false,
-  setItemList: [],
-  visibleBacklog: false,
-  visiblePreview: false, // 查看健康建议
-  interval: 30,
-  resultList: [],
-  result: "",
-  detail: {},
-  historyData: [],
-  currentTab: "indicator",
-  backlogItemList: [],
-  lastLevel: 0,
-  lastLevelName: "",
-  analyzeDetail: {}, // 智能评估详情
-  diseaseModels: [],
-  groupList: [], // 预防管理分组数据
-  group: undefined // 预防管理分组数据选中的分组
-});
-const metricInfo = reactive({
-  list: [],
-  projectList: [],
-  projectId: "",
-  nodeList: [],
-  nodes: []
-});
-const itemId = computed(() => {
-  return route.query.id;
-});
-const historyRef = ref([]);
-const isEvaluateTime = computed(() => {
-  if (!itemId.value) return;
-  return timeDiffer(state.detail?.nextTime?.split(" ")[0]) < 1;
-});
-const isEvaluate = computed(() => {
-  return route.query?.type == "evaluate";
-});
-const isCreate = computed(() => {
-  return !router.query?.type;
-});
-const isVisibleAnalyze = computed(() => {
-  if (!state.diseaseModels?.length) return false;
-  if (
-    state.diseaseModels.findIndex(v => v.diseaseId == route.query?.illnessId) >
-    -1
-  )
-    return true;
-});
-const isToday = () => {
-  return (
-    state?.detail?.createdAt?.split(" ")[0] == moment().format("YYYY-MM-DD")
-  );
-};
-const pageType = computed(() => {
-  return route.query?.type;
-});
-const evaluateDate = computed(() => {
-  // if(state?.detail?.createdAt?.split(" ")[0] == state)
-  return state?.detail?.nextTime?.split(" ")[0];
-});
-const IndicatorTrends = defineAsyncComponent(() =>
-  import("./components/IndicatorTrends.vue")
-);
-const CheckData = defineAsyncComponent(() =>
-  import("./components/PlanCheckData.vue")
-);
-const Archives = defineAsyncComponent(() =>
-  import("./components/PlanArchives.vue")
-);
-const AssessmentHistory = defineAsyncComponent(() =>
-  import("./components/AssessmentHistory.vue")
-);
-const DiseaseVisit = defineAsyncComponent(() =>
-  import("./components/DiseaseVisit.vue")
-);
-const DataCalcTool = defineAsyncComponent(() =>
-  import("./components/DataCalcTool.vue")
-);
-const menuList = [
-  {
-    name: "关键指标趋势",
-    key: "indicator",
-    component: IndicatorTrends
-  },
-  {
-    name: "检查数据汇总与对比",
-    key: "checkDataCollect",
-    component: CheckData
-  },
-  {
-    name: "评估历史记录",
-    key: "evaluationHistory",
-    component: AssessmentHistory
-  },
-  {
-    name: "疾病回访数据",
-    key: "visitIllness",
-    component: DiseaseVisit
-  },
-  {
-    name: "档案信息",
-    key: "archivalInformation",
-    component: Archives
-  },
-  {
-    name: "数据达标计算工具",
-    key: "DataCalcTool",
-    component: DataCalcTool
-  }
-];
-const illName = computed(() => {
-  return route.query.name;
-});
-const level = computed(() => Number(route.query.level) || "");
-const tagList = ref([]);
-const visibleHealthAdviceLibrary = ref(false);
-
-const handleCloseTag = index => {
-  tagList.value.splice(index, 1);
-};
-const handleGetSetItem = data => {
-  state.setItemList = data;
-  console.log("拿到的数据", data);
-};
-const handleBacklog = () => {
-  state.visibleBacklog = true;
-};
-const handleQuit = () => {
-  router.back();
-};
-const handleSaveIllness = () => {
-  tagList.value.push(state.problem);
-  state.problem = "";
-};
-const handleWatchSuggest = () => {
-  state.visiblePreview = true;
-};
-const handleChangeTab = value => {};
-const handleSet = () => {
-  // state.visibleSet = true;
-  router.replace(
-    `/healthManagement/evaluate?illnessId=${route.query.illnessId}&name=${illName.value}&id=${route.query?.id}&type=edit&archivesId=${currentArchiveId.value}&level=${level.value}`
-  );
-};
-const handleRecover = () => {
-  ElMessageBox.confirm("确定继续这个疾病的管理吗?", {
-    distinguishCancelAndClose: true,
-    confirmButtonText: "确定",
-    cancelButtonText: "取消"
-  })
-    .then(async () => {
-      request
-        .post("/platformApi/dataService/diseaseManage/update/status", {
-          id: state.detail?.id,
-          status: 0
-        })
-        .then(resp => {
-          ElMessage.success(resp.message);
-          getDetail();
-        });
-    })
-    .catch(err => {});
-};
-const getResultList = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 9999,
-        tag: "管理效果"
-      }
-    })
-    .then(resp => {
-      state.resultList = resp.data.list;
-    });
-};
-const getDiseaseModels = () => {
-  request
-    .get("/platformApi/dataService/diseaseManage/diseaseModels")
-    .then(resp => {
-      state.diseaseModels = resp.data;
-      nextTick(() => {
-        if (!isVisibleAnalyze.value) {
-          stepInit.value = true;
-        }
-      });
-      getDiseaseAnalysis();
-    });
-};
-const getDetail = () => {
-  // request
-  //   .get("/dataService/diseaseManage", {
-  //     params: {
-  //       id: itemId.value
-  //     }
-  //   })
-  //   .then(resp => {
-  //     state.detail = resp.data;
-  //     let { focus, effect, target, level, advise } = resp.data;
-  //     tagList.value = focus || [];
-  //     state.result = effect.id;
-  //     state.target = target;
-  //     state.level = level;
-  //     state.advise = advise;
-  //     getBacklogItemList();
-  //   });
-  request
-    .get("/dataService/diseaseManage/detail", {
-      params: {
-        archiveId: currentArchiveId.value
-      }
-    })
-    .then(resp => {
-      if (itemId.value) {
-        const current = resp.data.find(v => v.id == itemId.value);
-        state.detail = current;
-        state.historyData = transformDataExpand([current], "histories");
-
-        const {
-          focus,
-          effect,
-          target,
-          advise,
-          nextTime,
-          indicator,
-          group,
-          levelName
-        } = current;
-        if (pageType.value == "edit") {
-          tagList.value = state.detail.histories.length ? [] : focus; // 第二次评估不会显示上次存在的问题
-          state.result = effect.id;
-          state.target = target;
-          // state.level = level.value;
-          state.advise = advise;
-          metricInfo.list = indicator;
-          state.group = group;
-          state.interval = timeDiffer(moment(nextTime.split(" ")[0]));
-        } else {
-          state.interval = 30;
-        }
-
-        // state.interval = timeDiffer(moment(nextTime.split(" ")[0]));
-        state.lastLevel = level;
-        state.lastLevelName = levelName;
-      } else {
-        // state.historyData = transformDataExpand(resp?.data, "histories");
-        state.historyData = [];
-      }
-
-      getBacklogItemList();
-    });
-};
-
-const getBacklogItemList = () => {
-  if (!isEvaluate.value) return;
-  request
-    .get("dataService/schedule/todoList/duration", {
-      params: {
-        archiveId: currentArchiveId.value,
-        startDate: state?.detail?.createdAt?.split(" ")[0],
-        endDate: moment().format("YYYY-MM-DD"),
-        filter: 1
-      }
-    })
-    .then(resp => {
-      state.backlogItemList = resp.data;
-    });
-};
-const isNonZero = value => {
-  // 检验值是否为空(null, undefined, "" 或者 false)
-  if (value == null || value === "" || value === false) {
-    return false;
-  }
-  // 对于对象,检验是否有属性
-  if (typeof value === "object" && Object.keys(value).length === 0) {
-    return false;
-  }
-  // 其他情况视为非空
-  return true;
-};
-const handleSave = () => {
-  if (!state.result) {
-    return ElMessage.error("请选择目前健康状况评价");
-  }
-  if (!level.value) {
-    return ElMessage.error("请选择预防/管理级别");
-  }
-  if (!state.group) {
-    return ElMessage.error("请选择预防/管理分组");
-  }
-  if (!state.target) {
-    return ElMessage.error("请输入管理目标");
-  }
-  const params = {
-    archiveId: currentArchiveId.value,
-    disease: illName.value,
-    diseaseId: route.query?.illnessId,
-    focus: tagList.value,
-    effectId: state.result,
-    target: state.target,
-    level: level.value,
-    group: state.group,
-    nextTime: formatTime(state.interval)?.value,
-    advise: state.advise,
-    source: state.detail[0]?.source,
-    indicator: metricInfo.list
-  };
-  if (state.detail?.source) {
-    params.source = state.detail?.source;
-  }
-  if (pageType.value == "edit") {
-    params.id = Number(itemId.value);
-  }
-
-  request
-    .post(
-      pageType.value == "edit"
-        ? "/dataService/diseaseManage/update"
-        : "/dataService/diseaseManage/create",
-      params
-    )
-    .then(resp => {
-      ElMessage.success(resp.message);
-      router.back();
-    });
-};
-const formatTime = time => {
-  const count = Number(time);
-  const { years, months, date } = moment().toObject();
-  if (!count)
-    return {
-      label: `${years}年${months + 1}月${date}日`,
-      value: moment().format("YYYY-MM-DD")
-    };
-  const convertDate = moment()
-    .day(moment().day() + count)
-    .toObject();
-  return {
-    label: `${convertDate.years}年${convertDate.months + 1}月${
-      convertDate.date
-    }日`,
-    value: moment()
-      .day(moment().day() + count)
-      .format("YYYY-MM-DD")
-  };
-};
-const getDiseaseAnalysis = () => {
-  if (!isVisibleAnalyze.value) return;
-  request
-    .post("/dataService/diseaseManage/diseaseAnalysis", {
-      diseaseId: route.query?.illnessId,
-      archiveId: currentArchiveId.value
-    })
-    .then(resp => {
-      state.analyzeDetail = resp.data?.result;
-      needQA.value = state.analyzeDetail.needQA;
-    });
-};
-
-const needQA = ref(false);
-const QAHistoryDialogVisible = ref(false);
-const diseaseAnalysisResult = ref({
-  result: "",
-  reasons: []
-});
-const changeQAView = () => {
-  getDiseaseAnalysisResult();
-  QAHistoryDialogVisible.value = true;
-};
-const getDiseaseAnalysisResult = async () => {
-  const { data } = await request.get(
-    `/dataService/diseaseManage/diseaseAnalysis/result`,
-    {
-      params: {
-        diseaseId: route.query?.illnessId,
-        archiveId: currentArchiveId.value
-      }
-    }
-  );
-  diseaseAnalysisResult.value = data;
-};
-const diseaseQAConfirm = async assessmentInfo => {
-  await request.post("/dataService/diseaseManage/diseaseAnalysis/result", {
-    diseaseId: route.query?.illnessId,
-    archiveId: currentArchiveId.value,
-    result: assessmentInfo.result,
-    reasons: assessmentInfo.accordance,
-    errInfos: assessmentInfo.errInfo,
-    otherData: assessmentInfo.otherData
-  });
-  getDiseaseModels();
-  needQA.value = false;
-};
-
-const handleAddHealthAdviceLibrary = content => {
-  state.advise = content;
-};
-const searchNodes = async (type = 0, name = "") => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/query",
-    {
-      archivesId: route.query.archivesId,
-      itemIds: [],
-      nodeIds: [],
-      date: []
-    }
-  );
-  metricInfo.projectList = data.list || [];
-};
-
-const searchRelateNodes = async () => {
-  metricInfo.nodes = [];
-  metricInfo.nodeList =
-    metricInfo.projectList.find(v => {
-      return v.id == metricInfo.projectId;
-    })?.list || [];
-};
-const handleAddMetric = async () => {
-  if (!metricInfo.projectId) {
-    return ElMessage.error("请选择检查项目");
-  }
-  if (!metricInfo.nodes?.length) {
-    return ElMessage.error("请选择检查内容");
-  }
-  const currentProject = metricInfo.projectList.find(v => {
-    return v.id == metricInfo.projectId;
-  });
-  const hasExistIndex = metricInfo.list.findIndex(
-    v => v.id == metricInfo.projectId
-  );
-  if (hasExistIndex > -1) {
-    metricInfo.list.splice(hasExistIndex, 1);
-  } else {
-    currentProject.list = currentProject.list.filter(v =>
-      metricInfo?.nodes?.includes(v.id)
-    );
-    metricInfo.list.push(currentProject);
-  }
-
-  metricInfo.projectId = "";
-  metricInfo.nodes = [];
-  metricInfo.nodeList = [];
-};
-const handleDeleteMetric = (item, index) => {
-  metricInfo.list.splice(index, 1);
-};
-const getGroupList = () => {
-  if (!level.value) return;
-  request
-    .get(
-      `dataService/schemeManage/diseaseManageGroup/paginate?levelId=${level.value}`
-    )
-    .then(resp => {
-      state.groupList = resp.data.list;
-    });
-};
-const initData = async () => {
-  await getDiseaseModels();
-  searchNodes();
-  getGroupList();
-  getResultList();
-  getDetail();
-};
-initData();
-</script>
-<style scoped lang="scss">
-.el-scrollbar {
-}
-.el-form-item {
-  color: #333;
-  margin-bottom: 0;
-}
-</style>

+ 0 - 110
src/views/healthManagement/healthPPT.vue

@@ -1,110 +0,0 @@
-<template>
-  <div class="ppt-main" ref="healthPptMain" @click="fullscreen">
-
-    <div v-for="(item, index) in list" :ref="el => (imgRefs[index] = el)" class="w-screen h-screen animate__animated">
-      <el-image
-        :key="index"
-        :src="item"
-        class="w-full h-full select-none animate__animated"
-        alt=""
-        mode="contain"
-        fit="contain"
-      />
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { request } from "@/utils";
-import { nextTick } from "vue";
-import {
-  reactive,
-  computed,
-  ref,
-  provide,
-  onMounted,
-  onBeforeUnmount
-} from "vue";
-
-import { useRouter, useRoute } from "vue-router";
-const [route, router] = [useRoute(), useRouter()];
-const healthPptMain = ref()
-const imgRefs = ref([]);
-
-const pptNode = ref();
-const list = ref([]);
-const getPPTNode = async () => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 1,
-      pagesize: 1,
-      tag: "用户ID",
-      name: route.query.archivesId
-    }
-  });
-  if (data.list[0]) {
-    pptNode.value = data.list[0];
-    if (pptNode.value.properties) {
-      list.value = pptNode.value.properties["PPT地址"] || [];
-      imgRefs.value = Array(list.value.length).fill({});
-      nextTick(() => {
-        imgRefs.value.forEach(img => {
-          observer.observe(img);
-        });
-      });
-    }
-  }
-};
-getPPTNode();
-
-const observer = new IntersectionObserver(entries => {
-  console.log(entries);
-  entries.forEach(entry => {
-    console.log(entry);
-    if (entry.isIntersecting) {
-      entry.target.classList.add("animate__fadeIn");
-    } else {
-      // entry.target.classList.remove("animate__fadeInUp");
-    }
-  });
-});
-onMounted(() => {
-  // setTimeout(() => {
-  //   document.body.requestFullscreen()
-  // }, 10);
-  fullscreen()
-});
-
-onBeforeUnmount(() => {
-  imgRefs.value.forEach(img => {
-    observer.unobserve(img);
-  });
-});
-const fullscreen = () => {
-
-  document.body.requestFullscreen();
-}
-window.addEventListener('message', (event) => {
-    if (event.data === 'goFullscreen') {
-      healthPptMain.value.click();
-    }
-  });
-</script>
-
-<style lang="scss" scoped>
-body {
-  scroll-behavior: smooth;
-}
-.ppt-main {
-  overflow-x: hidden;
-  overflow-y: scroll; /* overflow 为 scroll,来把滚动条设置到 main 元素上 */
-  height: 100vh;
-  scroll-snap-type: y mandatory; /* scroll-snap-type 需要两个值,第一个值为滚动贴合的方向,y 表示纵向滚动贴合,第二个值为贴合方式,mandatory 表示强制滚动,用户只要一滚动鼠标,下一屏内容就直接滚动上来进行贴合。 */
-  // scroll-behavior: smooth; /* 添加平滑滚动效果 */
-  div {
-    place-items: center;
-    scroll-snap-align: center;
-  }
-}
-</style>

+ 0 - 487
src/views/healthManagement/healthPlan.vue

@@ -1,487 +0,0 @@
-<template>
-  <div class="page-health-plan p-2 w-full h-full flex flex-col">
-    <div class="flex items-center p-4 rounded bg-white shadow mb-2">
-      <!-- <div class="">
-      </div> -->
-      <div class="h-full grid grid-cols-2 grid-rows-2 gap-1">
-        <div
-          class="col-start-1 col-end-2 row-start-1 row-end-3 rounded p-2 flex items-center cursor-pointer bg-blue-100 hover:bg-blue-200 text-blue-600"
-          @click="openDiseaseManageDialog"
-        >
-          <img src="@/assets/icon-disease.png" alt="" class="w-5 mr-1" />
-          <span>{{ route.query?.name }}管理</span>
-          <ArrowRight class="w-4"></ArrowRight>
-        </div>
-        <div
-          class="col-start-2 col-end-3 row-start-1 row-end-2 rounded p-2 flex items-center cursor-pointer bg-green-100 hover:bg-green-200 text-green-600"
-          @click="historyVisible = true"
-        >
-          <Tickets class="w-4 mr-1" />
-          <span>评估记录</span>
-          <ArrowRight class="w-4"></ArrowRight>
-        </div>
-        <div
-          class="col-start-2 col-end-3 row-start-2 row-end-3 rounded p-2 flex items-center cursor-pointer bg-red-100 hover:bg-red-200 text-red-600"
-          @click="router.back()"
-        >
-          <SwitchButton class="w-4 mr-1" />
-          <span>退出管理</span>
-          <ArrowRight class="w-4"></ArrowRight>
-        </div>
-      </div>
-      <div class="flex items-center justify-around px-4 pt-10 flex-1">
-        <div
-          v-for="(item, index) in paths"
-          :key="index"
-          class="relative health-path-item py-2 px-4 rounded text-sm select-none cursor-pointer"
-          :class="item.class"
-          :style="current == index ? '' : 'opacity: 0.7'"
-          @click="changePath(item, index)"
-        >
-          <span>{{ item.label }}</span>
-          <div v-if="current == index" class="absolute -right-1 -top-1">
-            <span class="relative flex h-3 w-3">
-              <span
-                class="animate-ping absolute inline-flex h-full w-full rounded-full opacity-75"
-                :class="item.dotBgClass"
-              ></span>
-              <span
-                class="relative inline-flex rounded-full h-3 w-3"
-                :class="item.dotClass"
-              ></span>
-            </span>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div
-      class="flex-1 w-full rounded bg-white shadow"
-      style="height: calc(100% - 120px)"
-    >
-      <component
-        v-if="isInit && pathCaches.includes(current) && paths[current].component"
-        :is="paths[current].component"
-      ></component>
-    </div>
-
-    <el-dialog title="评估历史详情" v-model="historyVisible" width="85%">
-      <div>
-        <component
-          :is="DialogHealthManageEvaluationHistory"
-          :list="transformDataExpand(historyList, 'histories')"
-          ref="historyRef"
-        ></component>
-      </div>
-    </el-dialog>
-    <el-dialog
-      v-model="diseaseManageVisible"
-      :title="route.query.name + '管理'"
-    >
-      <div v-if="diseaseManageList.length" class="grid grid-cols-3 gap-4">
-        <div
-          v-for="(item, index) in diseaseManageList"
-          :key="index"
-          class="bg-white shadow p-4 rounded hover:bg-gray-50 cursor-pointer flex items-center"
-          @click="getDiseaseManageDetail(item)"
-        >
-          <img src="@/assets/icon-disease.png" alt="" class="w-5 mr-1" />
-          <div class="max-[10em] whitespace-nowrap truncate">
-            {{ item.label }}
-          </div>
-          <ArrowRight class="w-4 text-gray-500" />
-        </div>
-      </div>
-      <el-empty v-else :image="emptyImg"></el-empty>
-    </el-dialog>
-    <el-dialog
-      v-model="diseaseManageDetailVisible"
-      :title="diseaseManageDetail?.title"
-    >
-      <div v-html="diseaseManageDetail?.content"></div>
-    </el-dialog>
-  </div>
-</template>
-<script setup>
-import LeaderLine from "@/plugins/leader-line.min.js";
-
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  reactive,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick,
-  onUnmounted
-} from "vue";
-import { onBeforeRouteLeave, useRoute, useRouter } from "vue-router";
-import {
-  CopyDocument,
-  Fold,
-  TrendCharts,
-  Tickets,
-  SwitchButton,
-  ArrowLeft,
-  ArrowRight
-} from "@element-plus/icons-vue";
-import { request, sleep, transformDataExpand } from "@/utils";
-
-import emptyImg from "@/assets/icon-empty-left.png";
-const DialogHealthManageEvaluationHistory = defineAsyncComponent(() =>
-  import("./components/DialogHealthManageEvaluationHistory.vue")
-);
-const DataCollection = defineAsyncComponent(() =>
-  import("./healthPlan/DataCollection.vue")
-);
-const AnalysisOfEtiology = defineAsyncComponent(() =>
-  import("./healthPlan/AnalysisOfEtiology.vue")
-);
-const HealthPortrait = defineAsyncComponent(() =>
-  import("./healthPlan/HealthPortrait.vue")
-);
-const SituationAssessment = defineAsyncComponent(() =>
-  import("./healthPlan/SituationAssessment.vue")
-);
-const IndividualInterventionProgram = defineAsyncComponent(() =>
-  import("./healthPlan/IndividualInterventionProgram.vue")
-);
-const NextFeedbackSetting = defineAsyncComponent(() =>
-  import("./healthPlan/NextFeedbackSetting.vue")
-);
-
-const [route, router] = [useRoute(), useRouter()];
-const current = ref(0);
-const pathCaches = ref([0]);
-const changePath = (item, index) => {
-  !pathCaches.value.includes(index) && pathCaches.value.push(index);
-  current.value = index;
-};
-const paths = [
-  {
-    label: "数据收集",
-    component: DataCollection,
-    key: "DataCollection",
-    dotClass: "bg-green-500",
-    dotBgClass: "bg-green-400",
-    class: "text-green-800 bg-green-200" // 绿色代表数据和增长
-  },
-  {
-    label: "病因分析",
-    component: AnalysisOfEtiology,
-    key: "AnalysisOfEtiology",
-    dotClass: "bg-orange-500",
-    dotBgClass: "bg-orange-400",
-    class: "text-orange-800 bg-orange-300" // 橙色代表警示和关注
-  },
-  {
-    label: "健康画像",
-    component: HealthPortrait,
-    key: "HealthPortrait",
-    dotClass: "bg-blue-500",
-    dotBgClass: "bg-blue-400",
-    class: "text-blue-800 bg-blue-300" // 蓝色代表信任和可靠
-  },
-  {
-    label: "管理效果评价",
-    component: SituationAssessment,
-    key: "SituationAssessment",
-    dotClass: "bg-indigo-500",
-    dotBgClass: "bg-indigo-400",
-    class: "text-indigo-800 bg-indigo-300" // 靛青色代表分析和深度思考
-  },
-  {
-    label: "个性干预方案",
-    component: IndividualInterventionProgram,
-    key: "IndividualInterventionProgram",
-    dotClass: "bg-purple-500",
-    dotBgClass: "bg-purple-400",
-    class: "text-purple-800 bg-purple-300" // 紫色代表个性化和创新
-  },
-  {
-    label: "下次反馈设定",
-    component: NextFeedbackSetting,
-    key: "NextFeedbackSetting",
-    dotClass: "bg-teal-500",
-    dotBgClass: "bg-teal-400",
-    class: "text-teal-800 bg-teal-300" // 青色代表规划和未来
-  }
-];
-const pathLines = ref([]);
-const initPathLink = async () => {
-  pathLines.value = [];
-  const commonStyle = {
-    path: "grid",
-    color: "#0052D4",
-    gradient: {
-      startColor: "#65C7F7",
-      endColor: "#0052D4"
-    },
-    dash: {
-      animation: true
-    },
-    size: 2
-  };
-  await sleep(6e2);
-  const els = document.querySelectorAll(".health-path-item");
-  els.forEach((el, i) => {
-    let next = els[i + 1];
-    if (next) {
-      pathLines.value.push(
-        new LeaderLine(el, next, {
-          ...commonStyle,
-          startSocket: "right",
-          endSocket: "left",
-          path: "straight",
-          endPlug: "arrow1"
-        })
-      );
-    }
-  });
-
-  pathLines.value.push(
-    new LeaderLine(els[els.length - 1], els[0], {
-      ...commonStyle,
-      startSocket: "top",
-      endSocket: "top",
-      startPlug: "behind",
-      endPlug: "arrow1"
-    })
-  );
-  for (let i = 0; i < 6; i++) {
-    await sleep(16 * 4);
-    pathLinkLinePosition();
-  }
-};
-const pathLinkLinePosition = () => {
-  pathLines.value.forEach(v => v && v.position && v.position());
-};
-onMounted(async () => {
-  await getDetail();
-
-  initPathLink();
-  initDisease();
-});
-onUnmounted(() => {
-  pathLines.value.forEach(v => v.remove());
-});
-
-const state = ref({
-  archiveId: route.query.archivesId, // 档案号
-  disease: route.query.name, // 疾病名称
-  diseaseId: route.query.diseaseId, // 疾病id
-  etiologies: [], // 病因数组
-  effectId: "", // 目前管理效果评价id
-  target: "", // 下阶段期望效果
-  nextTime: "", // 下次评估时间
-  source: Number(route.query.source) || 0,
-  score: 100,
-  personalizeInterventions: [
-    // 个性化干预
-    // {
-    //   id: "", // 图数据库id
-    //   title: "", // 标题
-    //   content: "", // content
-    //   source: 0 // 历史记录里的source,第一次创建时传0
-    // }
-  ],
-  furtherInfo: [], // 进一步
-  additionalInfo: "" // 其他补充信
-});
-const isInit = ref(false)
-provide("parentState", state);
-const updateStateValueForKey = (key, value, source = "") => {
-  state.value[key] = value;
-  console.log(
-    "updateStateValueForKey",
-    "修改字段:",
-    key,
-    "修改值:",
-    value,
-    "完整数据:",
-    state.value,
-    "来源:",
-    source
-  );
-};
-provide("updateStateValueForKey", updateStateValueForKey);
-
-const getNodes = async query => {
-  const { data } = await request.get(`/graphService/open/node/paginate`, {
-    params: {
-      page: 1,
-      pageSize: 9999,
-      pagesize: 9999,
-      ...query
-    }
-  });
-  return data;
-};
-provide("getNodes", getNodes);
-const getNodeRelationship = async (id, tag, reverse = undefined) => {
-  const { data } = await request.get(`/graphService/open/node/relationship`, {
-    params: {
-      id,
-      rName: tag,
-      reverse
-    }
-  });
-  return data;
-};
-provide("getNodeRelationship", getNodeRelationship);
-const getBatchNodeRelationships = async (ids, tag, reverse = undefined) => {
-  const { data } = await request.get(`/graphService/open/node/relationships`, {
-    params: {
-      ids,
-      rName: tag,
-      reverse
-    }
-  });
-  return data;
-};
-provide("getBatchNodeRelationships", getBatchNodeRelationships);
-
-const getArticle = async id => {
-  const { data } = await request.get("/articleService/open/article", {
-    params: {
-      id,
-      mechanismId: "algor"
-    }
-  });
-  return data;
-};
-provide("getArticle", getArticle);
-const diseaseMangeNode = ref();
-const initDisease = async () => {
-  const nodes = await getNodeRelationship(
-    route.query.diseaseId,
-    "功能医学管理"
-  );
-  if (nodes[0]) {
-    diseaseMangeNode.value = nodes[0].mId;
-  }
-};
-provide("diseaseMangeNode", diseaseMangeNode);
-
-const openDiseaseManageDialog = () => {
-  getDiseaseManageList();
-  diseaseManageVisible.value = true;
-};
-const diseaseManageVisible = ref(false);
-const diseaseManageList = ref(false);
-const getDiseaseManageList = async () => {
-  const data = await getNodeRelationship(route.query.diseaseId, "疾病相关知识");
-  diseaseManageList.value = (data || []).map(v => {
-    return {
-      id: v.mId,
-      label: v.mProperties.name,
-      articleId: v.mProperties["文章ID"]
-    };
-  });
-};
-const diseaseManageDetailVisible = ref(false);
-const diseaseManageDetail = ref();
-const getDiseaseManageDetail = async item => {
-  diseaseManageDetail.value = await getArticle(item.articleId);
-  diseaseManageDetailVisible.value = true;
-};
-
-const historyVisible = ref(false);
-const historyList = ref([]);
-const getDetail = async () => {
-  const { data } = await request.get(
-    "/platformApi/dataService/healthManage/detail",
-    {
-      params: {
-        archiveId: route.query.archivesId
-      }
-    }
-  );
-  historyList.value = data.filter(v => v.diseaseId == route.query.diseaseId);
-  const last = historyList.value[0];
-  console.log('last', last)
-  if (last) {
-    state.value["diseaseId"] = last.diseaseId;
-    state.value["etiologies"] = last.etiologies || [];
-    state.value["score"] = last.score;
-    state.value["target"] = last.target;
-    state.value["nextTime"] = last.nextTime;
-    state.value["personalizeInterventions"] =
-      last.personalizeInterventions || [];
-    state.value["furtherInfo"] = last.furtherInfo || [];
-    state.value["additionalInfo"] = last.additionalInfo;
-  }
-  isInit.value =true
-};
-provide("healthHistoryList", historyList);
-
-const getSurveyFormByCode = async customFields => {
-  if (!customFields.length) return [];
-  const { data } = await request.post(
-    `/formService/mechanism/form/detailByCustomFields`,
-    {
-      customFields
-    }
-  );
-  return data?.formFields || [];
-};
-provide("getSurveyFormByCode", getSurveyFormByCode);
-
-const getFormFieldsSurveyIds = fields => {
-  let ids = [];
-  fields.forEach(v => {
-    if (v.fields?.length) {
-      v.fields.forEach(filed => {
-        if (filed.extra?.subjectIds) {
-          ids.push(...filed.extra.subjectIds);
-        } else {
-          filed.extra?.sn && ids.push(filed.extra?.sn);
-        }
-      });
-    }
-
-    if (v.extra?.subjectIds) {
-      ids.push(...v.extra.subjectIds);
-    } else {
-      v.extra?.sn && ids.push(v.extra.sn);
-    }
-  });
-  ids = [...new Set(ids)];
-  return ids;
-};
-provide("getFormFieldsSurveyIds", getFormFieldsSurveyIds);
-const getFormAnswer = async ids => {
-  if (!ids.length) return;
-  const { data } = await request.post(
-    `/archivesService/mechanism/form/data/query`,
-    {
-      archivesId: route.query.archivesId,
-      ids
-    }
-  );
-  return (data.list || []).map(v => {
-    return {
-      ...v,
-      answer: v.returnAnswer
-    };
-  });
-};
-provide("getFormAnswer", getFormAnswer);
-</script>
-
-<style lang="scss">
-.el-scrollbar__view {
-  height: 100%;
-  .main-content.page-health-plan {
-    margin: 0;
-  }
-}
-.page-health-plan {
-  overflow: hidden;
-  .data-container {
-    height: calc(100% - 48px);
-    width: 100%;
-  }
-}
-</style>

+ 0 - 272
src/views/healthManagement/healthPlan/AnalysisOfEtiology.vue

@@ -1,272 +0,0 @@
-<template>
-  <div class="h-full w-full flex">
-    <LeftMenu v-model:active="menuActive" :menus="menus" @change="menuChange">
-      <template #itemDesc="{ item }">
-        <div
-          class="rounded text-xs mt-2 border border-solid border-red-500 text-red-600 p-1 text-text w-fit"
-        >
-          已选{{ item.list.filter(v => v.checked).length }}个病因
-        </div>
-      </template>
-    </LeftMenu>
-    <div class="flex-1 h-full overflow-y-auto p-4 space-y-4">
-      <template v-if="menus[menuActive]?.id == 'additional'">
-        <div class="bg-white shadow p-4">
-          <div>
-            <el-input
-              v-model.trim="customEtiology"
-              class="w-fit"
-              placeholder="请输入其他自定义病因"
-            ></el-input>
-            <el-button type="primary" class="ml-2" @click="addCustomEtiology"
-              >添加</el-button
-            >
-          </div>
-          <el-divider></el-divider>
-          <div>
-            <el-tag
-              v-for="(tag, tagIdx) in menus[menuActive].list"
-              size="large"
-              :key="tagIdx"
-              type="danger"
-              closable
-              class="m-1"
-              @close="menus[menuActive].list.splice(tagIdx, 1)"
-              >{{ tag.label }}</el-tag
-            >
-          </div>
-        </div>
-      </template>
-      <template v-else>
-        <div
-          v-for="(item, index) in menus[menuActive]?.list"
-          :key="item.id"
-          class="bg-white shadow p-4 flex"
-        >
-          <component
-            :is="item.checked ? SuccessFilled : CircleCheck"
-            class="w-6 h-6 cursor-pointer"
-            :class="{
-              'text-blue-500': item.checked,
-              'text-gray-300': !item.checked
-            }"
-            @click="etiologiesChange(item)"
-          ></component>
-          <div class="flex-1 ml-2">
-            <div class="font-bold mb-3">{{ item.label }}</div>
-            <div
-              v-for="(text, textIdx) in item.remark"
-              :key="textIdx"
-              class="break-all whitespace-pre-wrap text-gray-500 py-1"
-            >
-              {{ text }}
-            </div>
-            <div v-if="item.transferRawJson && item.formFields" class="rounded mt-2 bg-gray-50">
-              <div class="mb-1 px-4 pt-2 text-sm text-gray-600">相关数据</div>
-              <component
-                v-if="item.transferRawJson && HealthArchivesModuleView"
-                :is="HealthArchivesModuleView"
-                :form="item.formFields"
-                :transferRawJson="item.transferRawJson"
-                class="text-sm"
-              ></component>
-            </div>
-            <div v-if="item.projectDataList.length" class="rounded mt-2 bg-gray-50">
-              <div class="mb-1 px-4 pt-2 text-sm text-gray-600">相关数据</div>
-              <component
-                v-if="item.projectDataList.length && HealthCheckData"
-                :is="HealthCheckData"
-                :list="item.projectDataList"
-              ></component>
-            </div>
-          </div>
-        </div>
-      </template>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import LeftMenu from "./LeftMenu.vue";
-import { request } from "@/utils";
-import { CircleCheck, SuccessFilled } from "@element-plus/icons-vue";
-import { ElMessage } from "element-plus";
-const [route, router] = [useRoute(), useRouter()];
-
-const HealthCheckData = defineAsyncComponent(() =>
-  import("./HealthCheckData.vue")
-);
-const HealthArchivesModuleView = defineAsyncComponent(() =>
-  import("./HealthArchivesModuleView.vue")
-);
-
-const updateStateValueForKey = inject("updateStateValueForKey");
-const menus = ref([]);
-const menuActive = ref(0);
-const getNodeRelationship = inject("getNodeRelationship");
-const diseaseMangeNode = inject("diseaseMangeNode");
-const getFormFieldsSurveyIds = inject('getFormFieldsSurveyIds')
-const getSurveyFormByCode = inject('getSurveyFormByCode')
-const getFormAnswer = inject('getFormAnswer')
-
-const parentState = inject("parentState");
-
-const getMenus = async () => {
-  const data = await getNodeRelationship(
-    diseaseMangeNode.value,
-    "功能医学病因分析分类"
-  );
-  menus.value = data.map(v => {
-    return {
-      label: v.mProperties?.name,
-      id: v.mId,
-      list: []
-    };
-  });
-  if (menus.value[0]?.id) {
-    menuChange(0, menus.value[0]);
-  }
-
-  const checkedEtiologies = parentState.value.etiologies.map(v => v.id);
-  const customEtiologies = parentState.value.etiologies.filter(v => v.type).map(v => ({...v, checked: true}));
-  
-  await Promise.all(
-    menus.value.map(async m => {
-      const data = await getNodeRelationship(m.id, "可能导致", 1);
-      m.list = data.map(v => {
-        const projectSetting = v.mProperties["关联检查项目"] || []
-        const projects = []
-        const projectNodes = []
-        projectSetting?.forEach && projectSetting.forEach(p => {
-          const arr = p.split ? p.split('||') : []
-          arr[0] && projects.push(arr[0])
-          arr.length > 1 && projectNodes.push(...arr.slice(1))
-        })
-        const temp = {
-          id: v.mId,
-          type: 0,
-          label: v.mProperties.name,
-          surveyTemplateCode: v.mProperties["关联问题模板编号"] || [],
-          surveyQuestionCode: v.mProperties["关联问题编号"] || [],
-          checkProjectId: projects,
-          checkProjectNodeId: projectNodes,
-          remark: v.mProperties["备注信息"],
-          checked: checkedEtiologies.includes(v.mId),
-          projectDataList: [],
-          transferRawJson: undefined,
-          formFields: undefined
-        };
-        console.log('temp.name, projects', temp.label, projects)
-        return temp;
-      });
-      m.list.forEach(async item => {
-        const surveyCode = [
-          ...item.surveyQuestionCode.map(v => ({ key: v, type: 2 })),
-          ...item.surveyTemplateCode.map(v => ({ key: v, type: 3 }))
-        ];
-        item.formFields = await getSurveyFormByCode(surveyCode);
-        const ids = getFormFieldsSurveyIds(item.formFields);
-        if (ids.length) {
-          item.transferRawJson = await getFormAnswer(ids);
-        }
-
-        if (item.checkProjectId.length) {
-          item.projectDataList = await getCheckData(item.checkProjectId, item.checkProjectNodeId)
-        }
-      });
-      console.log(m.list);
-    })
-  );
-  menus.value = [
-    ...menus.value,
-    {
-      label: "其他",
-      id: "additional",
-      list: customEtiologies || []
-    }
-  ];
-};
-getMenus();
-
-const allList = computed(() => menus.value.map(v => v.list).flat());
-const checkedList = computed(() =>
-  menus.value.map(v => v.list.filter(v => v.checked).map(v => v)).flat()
-);
-watch(
-  () => checkedList.value,
-  nv => {
-    updateStateValueForKey("etiologies", nv);
-  }
-);
-const etiologiesChange = item => {
-  item.checked = !item.checked;
-  console.log(checkedList.value);
-};
-
-const customEtiology = ref("");
-const addCustomEtiology = () => {
-  if (allList.value.map(v => v.label).includes(customEtiology.value)) {
-    return ElMessage.error("已存在该病因");
-  }
-  menus.value[menuActive.value].list.push({
-    id: "",
-    type: 1,
-    label: customEtiology.value,
-    surveyTemplateCode: [],
-    checkProjectId: [],
-    checkProjectNodeId: [],
-    remark: [],
-    checked: true
-  });
-  ElMessage.success("添加成功");
-  customEtiology.value = "";
-};
-const menuChange = async (i, menu) => {
-  console.log(i, menu);
-};
-
-
-
-const getCheckData = async (itemIds, nodeIds) => {
-  if (!itemIds.length) return;
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/query",
-    {
-      archivesId: route.query.archivesId,
-      itemIds,
-      nodeIds,
-      date: []
-    }
-  );
-  return (data?.list || []).map(v => {
-    v.expand = true;
-    v.list = v.list.map(v2 => {
-      const dateList = {};
-      v2.list.forEach(v3 => {
-        if (dateList[v3.date]) {
-          dateList[v3.date].push(v3);
-        } else {
-          dateList[v3.date] = [v3];
-        }
-        v2.list = Object.values(dateList);
-      });
-      return v2;
-    });
-    return v;
-  });
-}
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 160
src/views/healthManagement/healthPlan/DataCollection.vue

@@ -1,160 +0,0 @@
-<template>
-  <div class="h-full w-full flex">
-    <LeftMenu v-model:active="menuActive" :menus="menus" />
-    <div class="flex-1 h-full overflow-y-auto" :key="menuActive">
-      <template v-if="!menuActive">
-        <div class="p-4">
-          <Editor
-            v-model:value="recommendationDietaryAdvice"
-            @change="editorChange"
-          ></Editor>
-        </div>
-      </template>
-      <template v-else-if="menuActive == 1">
-        <div class="p-4">
-          <div class="shadow rounded flex items-center p-2">
-            <span>新增检查:</span>
-            <el-select
-              v-model="searchVal"
-              multiple
-              filterable
-              remote
-              :remote-method="q => searchProject(q)"
-            >
-              <el-option
-                v-for="(item, index) in searchList"
-                :key="index"
-                :label="item.label"
-                :value="item.id"
-              ></el-option
-            ></el-select>
-            <el-button
-              type="primary"
-              :disabled="!searchVal.length"
-              class="ml-2"
-              @click="addSearchVal"
-              >新增</el-button
-            >
-          </div>
-          <div class="mt-4 p-2 shadow rounded">
-            <el-table v-if="furtherInfo.length" :data="furtherInfo">
-              <el-table-column
-                label="检查项目"
-                prop="label"
-                width="200"
-              ></el-table-column>
-              <el-table-column label="检查意义" prop="tip"></el-table-column>
-              <el-table-column label="操作" width="100">
-                <template #default="{ row, $index }">
-                  <el-button
-                    type="danger"
-                    link
-                    @click="furtherInfo.splice($index, 1)"
-                    >移除</el-button
-                  >
-                </template>
-              </el-table-column>
-            </el-table>
-            <el-empty v-else :image="emptyImg" class=""> </el-empty>
-          </div>
-        </div>
-      </template>
-      <template v-else-if="menuActive == 2">
-        <component v-if="archives" :is="archives"></component>
-      </template>
-      <template v-else-if="menuActive == 3">
-        <component v-if="checkData" :is="checkData"></component>
-      </template>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import LeftMenu from "./LeftMenu.vue";
-import Editor from "@/components/Editor.vue";
-import emptyImg from "@/assets/icon-empty-right.png";
-import { debounce, deduplicateArrayByKeys } from "@/utils";
-
-const parentState = inject("parentState");
-const updateStateValueForKey = inject("updateStateValueForKey");
-const getNodes = inject("getNodes");
-const [route, router] = [useRoute(), useRouter()];
-
-const archives = defineAsyncComponent(() =>
-  import("../components/PlanArchives.vue")
-);
-const checkData = defineAsyncComponent(() =>
-  import("./HealthPlanCheckData.vue")
-);
-
-const menus = [
-  { label: "主要症状和描述" },
-  { label: "需要进一步的检查" },
-  { label: "问卷数据收集" },
-  { label: "检查数据收集" }
-];
-const menuActive = ref(0);
-const recommendationDietaryAdvice = ref(parentState.value.additionalInfo || "");
-const searchVal = ref([]);
-const searchList = ref([]);
-let cachesList = [];
-const searchProject = async (q, init = false) => {
-  if (!init && !q) return;
-  const data = await getNodes({
-    name: q,
-    tag: "医学检查项目",
-    pageSize: 50,
-    pagesize: 50
-  });
-  console.log(data);
-  cachesList = searchList.value.filter(v => searchVal.value.includes(v.id));
-  let temp = (data.list || []).map(v => {
-    return {
-      id: v.id,
-      label: v.properties.name,
-      tip: v.properties["检查意义"]
-    };
-  });
-  temp = deduplicateArrayByKeys([...temp, ...cachesList], ["id"]);
-  searchList.value = temp;
-};
-searchProject("", true);
-const addSearchVal = () => {
-  console.log(searchVal.value);
-  furtherInfo.value.push(
-    ...searchList.value.filter(v => searchVal.value.includes(v.id))
-  );
-  searchVal.value = [];
-};
-const furtherInfo = ref(parentState.value.furtherInfo || []);
-
-const editorChange = e => {
-  updateStateValueForKey(
-    "additionalInfo",
-    recommendationDietaryAdvice.value,
-    "测试"
-  );
-};
-watch(
-  () => furtherInfo.value,
-  () => {
-    updateStateValueForKey("furtherInfo", furtherInfo.value);
-  }
-);
-const defaultArchivesId = ref(route.query?.archivesId);
-provide("defaultArchivesId", defaultArchivesId);
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 4
src/views/healthManagement/healthPlan/FollowUpData.vue

@@ -1,4 +0,0 @@
-<template>
-  <div>随访数据</div>
-</template>
-<script setup></script>

+ 0 - 199
src/views/healthManagement/healthPlan/HealthArchivesModuleView.vue

@@ -1,199 +0,0 @@
-<template>
-	<div>
-    <div
-      v-if="(curIdx >= 0)"
-
-    >
-			<div
-				v-for="(item, index) in list"
-				:key="index"
-				class="py-2 px-4 mb-2 rounded-lg"
-      >
-        <div v-if="!props.isPlat && item.isModule" class="border-0">
-
-          <div class="text-base leading-8 ">{{ item.name }}</div>
-          <div
-            v-for="(child, childIdx) in item.children"
-            :key="childIdx"
-            class="py-2 px-4 border-0 border-b last:border-b-0 active:bg-gray-100 border-gray-100 border-solid"
-          >
-            <div class="flex flex-row justify-between items-center">
-              <div>
-                <div class="text-base leading-8">{{ child.name }}</div>
-                <div class="text-gray-500 text-sm">
-                  <div v-for="(moduleVal, moduleValIndex) in formateArchivesModuleValue(child, false)" :key="moduleValIndex" >
-
-                    <template v-if="moduleVal.isPlaceholder">
-                      <div v-html="moduleVal.value" :style="moduleVal.style"></div
-                    ></template>
-                    <template v-else>
-                      <span>{{ moduleVal.label }}</span>
-                      <template v-if="moduleVal.opt?.isFile">
-                        <span class="align-middle">:</span>
-                        <div v-for="(val, valIdx) in moduleVal.value" :key="valIdx" class="inline-block mr-2 drop-shadow">
-                          <el-image v-if="moduleVal.opt?.isImage(val.url)" :src="val.url" :alt="val.name" :preview-src-list="moduleVal.value.map(v => v.url)" preview-teleported :initial-index="valIdx" fit="cover" class="h-12 w-12 rounded align-middle"></el-image>
-                          <el-button v-else class="align-middle" type="primary" link tag="a" :download="val.name" :href="val.url + '?response-content-type=application/octet-stream'" target="_blank">下载附件</el-button>
-                        </div>
-                      </template>
-                      <span v-else class="text-gray-400">:{{ moduleVal.value }}{{ moduleVal.unit }}</span>
-                      <div v-if="moduleVal.date"><span>检查时间:</span><span class="text-gray-400">{{ moduleVal.date }}</span></div>
-                    </template>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div v-else class="flex flex-row justify-between items-center">
-          <div>
-            <div class="text-base leading-8">{{ item.name }}</div>
-            <div v-if="item.isModule" class="pl-4">
-
-              <div
-                v-for="(child, childIdx) in item.children"
-                :key="childIdx"
-
-              >
-                <div>
-                  <div
-                    v-for="(moduleVal, moduleValIndex) in formateArchivesModuleValue(child, false)" :key="moduleValIndex"
-                    class="py-2" :class="{
-                      'pl-2': moduleVal.isChild
-                    }">
-                    <template v-if="moduleVal.isPlaceholder">
-                      <div v-html="moduleVal.value" :style="moduleVal.style"></div
-                    ></template>
-                    <template v-else>
-                      <span>{{ moduleVal.label }}</span>
-                      <template v-if="!moduleVal.isLabel">
-                        <template v-if="moduleVal.opt?.isFile">
-                          <span class="align-middle">:</span>
-                          <div v-for="(val, valIdx) in moduleVal.value" :key="valIdx" class="inline-block mr-2 drop-shadow">
-                            <el-image v-if="moduleVal.opt?.isImage(val.url)" :src="val.url" :alt="val.name" :preview-src-list="moduleVal.value.map(v => v.url)" preview-teleported :initial-index="valIdx" fit="cover" class="h-12 w-12 rounded align-middle"></el-image>
-                            <el-button v-else class="align-middle" type="primary" link tag="a" :download="val.name" :href="val.url + '?response-content-type=application/octet-stream'" target="_blank">下载附件</el-button>
-                          </div>
-                        </template>
-                        <span v-else class="text-gray-400">:{{ moduleVal.value }}{{ moduleVal.unit }}</span>
-                      </template>
-                      <div v-if="moduleVal.date"><span>检查时间:</span><span class="text-gray-400">{{ moduleVal.date }}</span></div>
-                    </template>
-                  </div>
-                </div>
-              </div>
-              <div v-if="!item.children.find(v => v.hasValue)" class="text-gray-400">暂未填写</div>
-            </div>
-            <div v-else class="text-gray-500 text-sm">
-              <div v-for="(moduleVal, moduleValIndex) in formateArchivesModuleValue(item, false)" :key="moduleValIndex">
-                <template v-if="moduleVal.isPlaceholder">
-                  <div v-html="moduleVal.value" :style="moduleVal.style"></div
-                ></template>
-                <template v-else>
-                  <span>{{ moduleVal.label }}</span>
-                  <template v-if="!moduleVal.isLabel">
-                    <template v-if="moduleVal.opt?.isFile">
-                      <span class="align-middle">:</span>
-                      <div v-for="(val, valIdx) in moduleVal.value" :key="valIdx" class="inline-block mr-2 drop-shadow">
-                        <el-image v-if="moduleVal.opt?.isImage(val.url)" :src="val.url" :alt="val.name" :preview-src-list="moduleVal.value.map(v => v.url)" preview-teleported :initial-index="valIdx" fit="cover" class="h-12 w-12 rounded align-middle"></el-image>
-                        <el-button v-else class="align-middle" type="primary" link tag="a" :download="val.name" :href="val.url + '?response-content-type=application/octet-stream'" target="_blank">下载附件</el-button>
-                      </div>
-                    </template>
-                    <span v-else class="text-gray-400">:{{ moduleVal.value }}{{ moduleVal.unit }}</span>
-                  </template>
-                  <div v-if="moduleVal.date"><span>检查时间:</span><span class="text-gray-400">{{ moduleVal.date }}</span></div>
-                </template>
-              </div>
-
-              <div v-if="!item.hasValue" class="text-gray-400">暂未填写</div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-<script setup>
-import { computed, watch, ref, reactive, inject, onActivated,onMounted, defineAsyncComponent } from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { request, formateArchivesModuleValue } from '@/utils';
-
-const props = defineProps({
-  transferRawJson: {
-    type: Object,
-    default: undefined
-  },
-  isPlat: {
-    type: Boolean,
-    default: false
-  },
-  form: {
-    type: Object,
-    default: undefined
-  },
-  moduleId: {
-    type: String,
-    default: undefined
-  }
-})
-const list = ref([])
-const test = ref()
-
-
-const route = useRoute()
-const router = useRouter()
-const curIdx = ref(0)
-const moduleList = ref([])
-
-const fetchModuleIndicators = async () => {
-  list.value = props?.form || []
-  console.log(list.value, props?.form);
-  getFillFormData()
-}
-const transferRawJson = ref(props.transferRawJson)
-const getFillFormData = async () => {
-  console.log(transferRawJson)
-  const returnAnswer = {}
-  ;(transferRawJson.value || []).forEach((v, k) => {
-    returnAnswer[v.answer.questionNo] = v.answer
-  })
-  console.log('return answer', returnAnswer);
-
-  fillFormData(list.value, returnAnswer)
-  console.log('test', list.value);
-}
-const fillFormData = (arr, data) => {
-
-  arr.forEach(v => {
-    if (v.fields?.length) {
-      v.fields.forEach(filed => {
-        if (filed.extra?.subjects) {
-          filed.extra?.subjects.forEach(subject => {
-            subject.returnAnswer = data[subject.sn]
-          })
-        } else {
-          if (filed.extra?.sn) {
-            filed.extra.returnAnswer = data[filed.extra.sn]
-          }
-        }
-      })
-    }
-    if (v.extra?.subjects) {
-      v.extra?.subjects.forEach(subject => {
-        subject.returnAnswer = data[subject.sn]
-      })
-    } else {
-      if (v.extra?.sn) {
-        v.extra.returnAnswer = data[v.extra.sn]
-      }
-    }
-  })
-  return arr
-}
-watch(() => [props.form, props.transferRawJson], () => {
-  fetchModuleIndicators()
-}, {
-  immediate: true,
-})
-
-</script>
-<style lang="scss">
-</style>

+ 0 - 91
src/views/healthManagement/healthPlan/HealthCheckData.vue

@@ -1,91 +0,0 @@
-<template>
-
-  <div class="p-4 space-y-4 ">
-    <div v-for="(item, index) in list" :key="index" class="shadow">
-      <div
-        class="cursor-pointer py-2 px-4 flex items-center justify-between"
-        :class="{
-          'bg-gray-50': !item.expand,
-          'bg-blue-50 text-blue-700': item.expand
-        }"
-        @click="item.expand = !item.expand"
-      >
-        <span>{{ item.name }}</span>
-        <ArrowUp class="w-4 text-gray-500" v-if="!item.expand" />
-        <ArrowDown class="w-4 text-gray-500" v-else />
-      </div>
-      <div class="w-full overflow-x-auto">
-        <table
-          v-if="item.expand"
-          class="min-w-full bg-white text-gray-700 table-fixed"
-        >
-          <tr class="font-bold">
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-            >
-              项目
-            </td>
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-              v-for="(col, index) in item.list?.[0]?.list"
-              :key="index"
-            >
-              {{ dayjs(col[0].date * 1000).format("YYYY-MM-DD HH:mm:ss") }}
-            </td>
-          </tr>
-          <tr v-for="(child, childIdx) in item.list" :key="childIdx">
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-            >
-              {{ child.name }}
-            </td>
-            <td
-              v-for="(col, colIdx) in child.list"
-              :key="colIdx"
-              class="border border-solid border-gray-100"
-            >
-              <div class="p-2 text-sm">
-                <div v-for="(subCol, subColIdx) in col" :key="subColIdx">
-                  <span class="align-middle"
-                    >{{ subCol.value
-                    }}{{ subCol.unit && subCol.unit != "-" ? subCol.unit : "" }}
-                  </span>
-                  <template v-if="subCol.reference">
-                    <el-tooltip>
-                      <QuestionFilled
-                        class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                      />
-                      <template #content>
-                        <div class="text-sm">参考范围:{{ subCol.reference }}</div>
-                      </template>
-                    </el-tooltip>
-                  </template>
-                </div>
-              </div>
-            </td>
-          </tr>
-        </table>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed, watch, provide } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import { useRoute, useRouter } from "vue-router";
-
-import { request } from "@/utils";
-import dayjs from "dayjs";
-import { QuestionFilled, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-
-const props = defineProps({
-  list: {
-    type: Array,
-    default: undefined
-  }
-})
-const list = computed(() => props.list || []);
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 158
src/views/healthManagement/healthPlan/HealthPlanCheckData.vue

@@ -1,158 +0,0 @@
-<template>
-  <!-- <div class="bg-[#f0f2f5] sticky z-10 top-0 h-4"></div> -->
-
-  <div class="p-4 space-y-4 ">
-    <div v-for="(item, index) in list" :key="index" class="shadow">
-      <div
-        class="cursor-pointer py-2 px-4 flex items-center justify-between"
-        :class="{
-          'bg-gray-50': !item.expand,
-          'bg-blue-50 text-blue-700': item.expand
-        }"
-        @click="item.expand = !item.expand"
-      >
-        <span>{{ item.name }}</span>
-        <ArrowUp class="w-4 text-gray-500" v-if="!item.expand" />
-        <ArrowDown class="w-4 text-gray-500" v-else />
-      </div>
-      <div class="w-full overflow-x-auto">
-        <table
-          v-if="item.expand"
-          class="min-w-full bg-white text-gray-700 table-fixed"
-        >
-          <tr class="font-bold">
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-            >
-              项目
-            </td>
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-              v-for="(col, index) in item.list?.[0]?.list"
-              :key="index"
-            >
-              {{ dayjs(col[0].date * 1000).format("YYYY-MM-DD HH:mm:ss") }}
-            </td>
-          </tr>
-          <tr v-for="(child, childIdx) in item.list" :key="childIdx">
-            <td
-              class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-            >
-              {{ child.name }}
-            </td>
-            <td
-              v-for="(col, colIdx) in child.list"
-              :key="colIdx"
-              class="border border-solid border-gray-100"
-            >
-              <div class="p-2 text-sm">
-                <div v-for="(subCol, subColIdx) in col" :key="subColIdx">
-                  <span class="align-middle"
-                    >{{ subCol.value
-                    }}{{ subCol.unit && subCol.unit != "-" ? subCol.unit : "" }}
-                  </span>
-                  <template v-if="subCol.reference">
-                    <el-tooltip>
-                      <QuestionFilled
-                        class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                      />
-                      <template #content>
-                        <div class="text-sm">参考范围:{{ subCol.reference }}</div>
-                      </template>
-                    </el-tooltip>
-                  </template>
-                </div>
-              </div>
-            </td>
-          </tr>
-        </table>
-      </div>
-    </div>
-    <el-empty v-if="!list.length"></el-empty>
-  </div>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted, watch, provide, inject } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import { useRoute, useRouter } from "vue-router";
-
-import { request } from "@/utils";
-import dayjs from "dayjs";
-import { QuestionFilled, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-const route = useRoute();
-const router = useRouter();
-
-const getNodeRelationship = inject("getNodeRelationship");
-const diseaseMangeNode = inject("diseaseMangeNode");
-
-const projects = ref([]);
-const list = ref([]);
-const search = async () => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/query",
-    {
-      archivesId: route.query.archivesId,
-      itemIds: projects.value.map(v => v.id),
-      nodeIds: [],
-      date: []
-    }
-  );
-  list.value = (data.list || []).map(v => {
-    v.expand = true;
-    v.list = v.list.map(v2 => {
-      const dateList = {};
-      v2.list.forEach(v3 => {
-        if (dateList[v3.date]) {
-          dateList[v3.date].push(v3);
-        } else {
-          dateList[v3.date] = [v3];
-        }
-        v2.list = Object.values(dateList);
-      });
-      return v2;
-    });
-    return v;
-  });
-  console.log(list.value)
-};
-
-const recognitionType = ["医学检查项目", "身体物质/部位"];
-
-const relatedRelationship = ["异常属于", "可检测"];
-const searchNodes = async (type = 0, name = "") => {
-  // const { data } = await request.post(
-  //   "/idcService/mechanism/medicalData/transferItem/query",
-  //   {
-  //     archivesId: route.query.archivesId,
-  //     itemIds: [],
-  //     nodeIds: [],
-  //     date: []
-  //   }
-  // );
-  // projects.value = data.list || []
-  const data = await getNodeRelationship(diseaseMangeNode.value, '功能医学关注的检查')
-  projects.value = (data || []).map(v => {
-    return {
-      id: v.mId,
-      label: v.mProperties?.name
-    }
-  })
-
-};
-const searchRelateNodes = async () => {
-  nodes.value = filter.value.project
-    .map(id => {
-      return projects.value.find(v => v.id == id)?.list || [];
-    })
-    .flat();
-};
-
-const init = async () => {
-  await searchNodes();
-  search();
-};
-init();
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 566
src/views/healthManagement/healthPlan/HealthPortrait.vue

@@ -1,566 +0,0 @@
-<template>
-  <div class="h-full w-full flex">
-    <div class="h-full p-4">
-      <div
-        class="h-full bg-white p-4 rounded shadow border border-solid border-gray-200"
-      >
-        <component
-          :is="gender != '女' ? bodyManImg : bodyWomanImg"
-          class="w-auto h-full"
-        ></component>
-      </div>
-    </div>
-    <div class="flex-1 h-full overflow-y-auto p-4 pl-0">
-      <div
-        class="bg-white border border-solid border-gray-200 shadow p-2 rounded mb-4"
-      >
-        <div class="p-2 font-bold">时间线</div>
-        <div class="overflow-x-auto">
-          <table class="min-w-full">
-            <tr class="border-b border-solid border-gray-200">
-              <td class="whitespace-nowrap p-2">家族史</td>
-              <td
-                v-if="timeline && timeline[0]"
-                :colspan="Object.keys(timeline[0]?.list).length"
-                class="p-2 py-4"
-              >
-                <el-tag
-                  v-for="(item, index) in portrait.find(v => v.sort == 6)
-                    ?.list || []"
-                  :key="index"
-                  class="mr-2 text-sm"
-                  type="danger"
-                  >{{ item.label }}:{{ item.value }}</el-tag
-                >
-              </td>
-            </tr>
-            <tr
-              v-for="(item, index) in timeline"
-              :key="index"
-              class="border-b border-solid border-gray-200"
-            >
-              <td class="whitespace-nowrap p-2 py-3 pr-4">{{ item.label }}</td>
-              <td
-                v-for="(time, timeIdx) in item.list"
-                :key="timeIdx"
-                class="px-2 py-4"
-                :class="{
-                  'dotted-column': time?.length
-                }"
-              >
-                <div v-if="time?.length" class="space-y-2">
-                  <div
-                    v-for="(sub, subIdx) in time"
-                    :key="subIdx"
-                    class="whitespace-nowrap"
-                  >
-                    <span>{{ sub.label }}</span>
-                    <el-tag class="ml-1">
-                      <span
-                        >{{ sub.startAge
-                        }}{{
-                          sub.startAge && sub.startAge != "至今" ? "岁" : ""
-                        }}</span
-                      >
-                      <span v-if="sub.startAge && sub.endAge">-</span>
-                      <span
-                        >{{ sub.endAge
-                        }}{{
-                          sub.endAge && sub.endAge != "至今" ? "岁" : ""
-                        }}</span
-                      >
-                    </el-tag>
-                  </div>
-                </div>
-              </td>
-            </tr>
-            <tr class="whitespace-nowrap">
-              <td class="p-2"></td>
-              <td
-                v-for="(item, index) in Object.keys(timeline[0]?.list || [])"
-                :key="index"
-                class="px-2 py-4 text-sm text-gray-500 text-center"
-              >
-                {{
-                  timeline.find(v => v.list[item]?.length) ? `${item}年` : ""
-                }}
-              </td>
-            </tr>
-          </table>
-          <el-skeleton v-if="!timeline.length" :rows="5" />
-        </div>
-      </div>
-      <div class="grid grid-cols-3 gap-4">
-        <div
-          v-for="(item, index) in portrait"
-          :key="item.sort"
-          class="text-sm bg-white border border-solid border-gray-200 shadow p-2 rounded"
-        >
-          <div class="text-base p-2 font-bold text-gray-800">
-            {{ item.label }}
-          </div>
-          <div
-            class="p-2"
-            :class="portraitClass[item.sort] || portraitClass.default"
-          >
-            <template v-if="item.type == 'additionalInfo'">
-              <div class="h-[150px] overflow-y-auto">
-                <div v-if="additionalInfo" v-html="additionalInfo"></div>
-                <div v-else class="text-sm text-gray-500">暂未填写</div>
-              </div>
-            </template>
-            <template v-else-if="item.type == 'etiologies'">
-              <div v-if="etiologies.length">
-                <el-tag
-                  v-for="(child, childIdx) in etiologies"
-                  :key="childIdx"
-                  class="m-1"
-                  type="danger"
-                  >{{ child.label }}</el-tag
-                >
-              </div>
-              <div v-else class="text-sm text-gray-500">暂未选择</div>
-            </template>
-            <template v-else-if="item.type == 'lifeHabit'">
-              <div class="max-h-[150px] overflow-auto">
-                <component
-                  v-if="item.type == 'lifeHabit' && lifeHabitTransferRawJson && HealthArchivesModuleView"
-                  :is="HealthArchivesModuleView"
-                  :form="lifeHabitFields"
-                  :transferRawJson="lifeHabitTransferRawJson"
-                  class="text-sm"
-                ></component>
-              </div>
-            </template>
-            <div
-              v-else
-              v-for="(child, childIdx) in item.list"
-              :key="childIdx"
-              class="flex items-start"
-            >
-              <div v-if="child.label" class="mr-2 whitespace-nowrap">
-                {{ child.label }}:
-              </div>
-              <div
-                class="text-gray-600"
-                :class="{
-                  'flex flex-wrap': item.sort == 4 || item.sort == 5
-                }"
-              >
-                <template v-if="child.list?.length">
-                  <div
-                    v-for="(child, childIdx) in child.list"
-                    :key="childIdx"
-                    class="flex items-start"
-                  >
-                    <div v-if="child.label" class="mr-2 whitespace-nowrap">
-                      {{ child.label }}:
-                    </div>
-                    <template v-if="Array.isArray(child.value)">
-                      <el-tag
-                        v-for="(t, tIdx) in child.value"
-                        :key="tIdx"
-                        :class="{
-                          'mr-1 mb-1': item.sort == 4 || item.sort == 5
-                        }"
-                      >
-                        <span class="inline-block align-middle">{{ t }} </span>
-                        <QuestionFilled
-                          v-if="medicineDetail[child.key]"
-                          :key="child.key"
-                          class="w-4 ml-2 cursor-pointer inline-block align-middle"
-                          @click="openMedicineDetail(child.key)"
-                        />
-                      </el-tag>
-                    </template>
-                    <span v-else>{{ child.value }}</span>
-                  </div>
-                </template>
-                <span v-else>{{ child.value }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-      <div  v-if="!portrait.length" class="p-4">
-        <el-skeleton :rows="5" />
-      </div>
-      <div
-        v-for="(item, index) in keyIndictorChartData"
-        :key="index"
-        class="bg-white border border-solid border-gray-200 shadow p-2 rounded mt-4"
-      >
-        <div class="p-2 font-bold">关键指标-{{ item.name }}</div>
-        <div>
-          <div v-if="item.isBodyMatter" class="h-64">
-            <Chart
-              :ref="
-                r => {
-                  chartRefs[index] = r;
-                }
-              "
-            />
-          </div>
-          <div v-else class="w-full overflow-x-auto">
-            <table class="min-w-full bg-white text-gray-700 table-fixed">
-              <tr class="font-bold">
-                <td class="border border-solid border-gray-100 p-2"></td>
-                <td
-                  class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-                  v-for="(col, index) in item.list"
-                  :key="index"
-                >
-                  {{ dayjs(col.date * 1000).format("YYYY-MM-DD") }}
-                </td>
-              </tr>
-              <tr>
-                <td
-                  class="border border-solid border-gray-100 p-2 whitespace-nowrap"
-                >
-                  {{ item.name }}
-                </td>
-                <td
-                  v-for="(col, colIdx) in item.list"
-                  :key="colIdx"
-                  class="border border-solid border-gray-100"
-                >
-                  <div class="p-2 text-sm">
-                    <span class="align-middle"
-                      >{{ col.value }}
-                      {{ col.unit && col.unit != "-" ? col.unit : "" }}
-                    </span>
-                    <template v-if="col.reference">
-                      <el-tooltip>
-                        <QuestionFilled
-                          class="w-4 h-4 inline align-middle ml-1 cursor-pointer opacity-50"
-                        />
-                        <template #content>
-                          <div class="text-sm">
-                            参考范围:{{ col.reference }}
-                          </div>
-                        </template>
-                      </el-tooltip>
-                    </template>
-                  </div>
-                </td>
-              </tr>
-            </table>
-          </div>
-        </div>
-      </div>
-    </div>
-    <el-dialog v-model="medicineDialogVisible" title="药品知识">
-      <div class="flex items-start h-[600px]">
-        <div class="h-full w-[200px] overflow-y-auto bg-gray-50 p-2">
-          <div
-            v-for="(item, index) in medicineDialogDetail.menus"
-            :key="index"
-            class="flex items-center justify-between cursor-pointer px-2 py-4 hover:bg-gray-100 border-b border-solid border-gray-200 last:border-b-0"
-            :class="{
-              'text-blue-500': index == medicineDialogDetail.active
-            }"
-            @click="medicineDialogDetail.active = index"
-          >
-            <span>{{ item.label }}</span>
-            <ArrowRight class="w-4" />
-          </div>
-        </div>
-        <div class="h-full flex-1 overflow-y-auto">
-          <div class="whitespace-pre-wrap break-all p-4">
-            {{
-              medicineDialogDetail.detail[
-                medicineDialogDetail.menus[medicineDialogDetail.active].label
-              ] || '暂无数据'
-            }}
-          </div>
-        </div>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick,
-  shallowRef
-} from "vue";
-import { QuestionFilled, ArrowRight } from "@element-plus/icons-vue";
-import dayjs from "dayjs";
-import { useRoute, useRouter } from "vue-router";
-
-import bodyManImg from "@/assets/body-man.svg?component";
-import bodyWomanImg from "@/assets/body-woman.svg?component";
-import { request } from "@/utils";
-import Chart from "@/components/Chart.vue";
-
-const [route, router] = [useRoute(), useRouter()];
-
-const parentState = inject("parentState");
-const getNodes = inject("getNodes");
-const getBatchNodeRelationships = inject("getBatchNodeRelationships");
-
-const getFormFieldsSurveyIds = inject("getFormFieldsSurveyIds");
-const getSurveyFormByCode = inject("getSurveyFormByCode");
-const getFormAnswer = inject("getFormAnswer");
-const diseaseMangeNode = inject("diseaseMangeNode");
-
-const HealthArchivesModuleView = defineAsyncComponent(() =>
-  import("./HealthArchivesModuleView.vue")
-);
-const gender = ref();
-const portrait = ref([]);
-const timeline = ref([]);
-const portraitClass = {
-  default: "space-y-2",
-  1: "grid grid-cols-3 gap-2"
-};
-const keyIndictorList = ref([]);
-const medicineDetail = ref({});
-const init = async () => {
-  const { data } = await request.get(
-    `/archivesService/mechanism/archives/portrait`,
-    {
-      params: {
-        archivesId: route.query.archivesId
-      }
-    }
-  );
-  data.list.splice(
-    1,
-    0,
-    {
-      label: "主要症状和体征描述",
-      type: "additionalInfo",
-      sort: 2
-    },
-    {
-      label: "当前病因因素",
-      type: "etiologies",
-      sort: 3
-    }
-  );
-
-  portrait.value = data.list;
-  timeline.value = data.timeline || [];
-  getLifeHabitDetail(data.lifeHabitIds);
-  const medicineList =
-    portrait.value
-      .find(v => v.sort == 5)
-      .list.map(v => v.list)
-      .flat() || [];
-
-  gender.value =
-    portrait.value.find(v => v.sort == 1)?.list.find(v => v.sort == 2)?.value ||
-    "男";
-  if (medicineList.length) {
-    console.log("medicineList", medicineList);
-    getMedicineData(medicineList.filter(v => v.key).map(v => v.key));
-  }
-  const keyIndictor = await getBatchNodeRelationships(
-    diseaseMangeNode.value,
-    "关键管理指标"
-  );
-  keyIndictorList.value = keyIndictor.map(v => {
-    return {
-      id: v.mId,
-      label: v.mProperties.name
-    };
-  });
-  getKeyIndictorChartData();
-};
-const additionalInfo = computed(() => parentState.value.additionalInfo);
-const etiologies = computed(() => parentState.value.etiologies);
-onMounted(() => {
-  init();
-});
-
-const lifeHabitFields = ref([])
-const lifeHabitTransferRawJson = ref()
-const getLifeHabitDetail = async lifeHabitIds => {
-  const formFields = await getSurveyFormByCode(lifeHabitIds);
-  lifeHabitFields.value = formFields
-  const ids = getFormFieldsSurveyIds(formFields);
-  if (ids.length) {
-    lifeHabitTransferRawJson.value = await getFormAnswer(ids);
-    portrait.value.splice(portrait.value.length, 0, {
-      label: "生活习惯",
-      type: "lifeHabit",
-      sort: 9
-    });
-  }
-};
-
-const keyIndictorChartData = ref([]);
-const getKeyIndictorChartData = async () => {
-  const { data } = await request.post(
-    "/idcService/mechanism/medicalData/transferItem/primaryIndicatorCharts/query",
-    {
-      archivesId: route.query.archivesId,
-      nodeIds: keyIndictorList.value.map(v => v.id),
-      dates: [],
-      needCharts: true
-    }
-  );
-  keyIndictorChartData.value = data.list;
-  nextTick(() => {
-    keyIndictorChartData.value.forEach((v, i) => {
-      v.isBodyMatter && setOption(chartRefs.value[i], v);
-    });
-  });
-};
-
-const getMedicineData = async ids => {
-  if (!ids.length) return
-  const data = await getNodes({
-    id: ids.join()
-  });
-  const result = {};
-  (data.list || []).forEach(v => {
-    result[v.id] = {
-      id: v.id,
-      ...v.properties
-    };
-  });
-  medicineDetail.value = result;
-  console.log("medicineDetail.value", medicineDetail.value);
-};
-const medicineDialogVisible = ref(false);
-const medicineDialogDetail = ref({
-  id: "",
-  active: 0,
-  menus: [
-    {
-      label: "副作用"
-    },
-    {
-      label: "用药指导"
-    },
-    {
-      label: "功效"
-    }
-  ],
-  detail: {}
-});
-const openMedicineDetail = id => {
-  medicineDialogDetail.value.id = id;
-  medicineDialogDetail.value.active = 0;
-  medicineDialogDetail.value.menus = (medicineDetail.value[id]?._keys || []).map(v => ({label: v}));
-  medicineDialogDetail.value.detail = medicineDetail.value[id];
-
-  medicineDialogVisible.value = true;
-  // console.log('medicineDialogDetail.value.menus', medicineDialogDetail.value)
-};
-const chartRefs = ref([]);
-const setOption = (cRef, item) => {
-  console.log(cRef, item);
-  const opt = {
-    title: {
-      text: item.name,
-      top: "10",
-      left: "10"
-    },
-    grid: {
-      left: "5%",
-      right: "5%",
-      bottom: "20%"
-    },
-    legend: {
-      top: "bottom"
-    },
-    xAxis: {
-      type: "category",
-      data: []
-    },
-    tooltip: {
-      formatter(param) {
-        return `${param.seriesName}: ${param.value}${param.data?.unit}`;
-      }
-    },
-    yAxis: {
-      type: "value",
-      axisLine: { show: false },
-      axisTick: { show: false }
-      // axisLabel: { show: false }
-    },
-    series: []
-  };
-  if (item.name == "血压") {
-    const arr1 = [];
-    const arr2 = [];
-    item.list.forEach(v => {
-      const val = v.value.split("/");
-      arr1.push({
-        ...v,
-        value: val[0]
-      });
-      arr2.push({
-        ...v,
-        value: val[1]
-      });
-    });
-
-    opt.series = [
-      {
-        name: "收缩压",
-        data: arr1,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      },
-      {
-        name: "舒张压",
-        data: arr2,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      }
-    ];
-  } else {
-    opt.series = [
-      {
-        name: item.name,
-        data: item.list,
-        type: "line",
-        label: {
-          show: true
-        },
-        smooth: true
-      }
-    ];
-  }
-  opt.series.forEach(v => {
-    v.data = v.data
-      .map(d => {
-        const val = /(\d+(\.\d+)?)/.exec(String(d.value));
-        if (val) {
-          d.value = val[0] || d.value;
-        }
-        if (isNaN(Number(d.value))) {
-          d.value = null;
-        }
-        return d;
-      })
-      .filter(d => d.value != null);
-  });
-  opt.xAxis.data = opt.series[0].data.map(d =>
-    dayjs(d.date * 1000).format("YYYY-MM-DD")
-  );
-  console.log(opt);
-
-  cRef && cRef.setOption(opt);
-};
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 295
src/views/healthManagement/healthPlan/IndividualInterventionProgram.vue

@@ -1,295 +0,0 @@
-<template>
-  <div class="h-full w-full flex">
-    <LeftMenu v-model:active="menuActive" :menus="menus" @change="menuChange" />
-    <div class="flex-1 h-full overflow-y-auto p-4">
-      <template v-if="!menuActive">
-        <div v-for="(item, index) in menus.slice(1)" :key="index">
-          <template v-if="item.content && item.content != '<p><br></p>'">
-            <div class="font-bold mt-2 mb-2">{{ item.title }}:</div>
-            <div class="p-4 bg-gray-50 rounded">
-              <div v-html="item.content"></div>
-            </div>
-          </template>
-        </div>
-        <el-empty
-          v-if="
-            !menus
-              .slice(1)
-              .filter(v => v.content && v.content != '<p><br></p>').length
-          "
-          :image="emptyImg"
-          class=""
-        >
-          <template #description>
-            <el-button
-              v-if="menus[1]"
-              type="primary"
-              link
-              plain
-              @click="
-                menuActive = 1;
-                menuChange(1, menus[1]);
-              "
-              >暂未填写,去填写</el-button
-            >
-          </template>
-        </el-empty>
-      </template>
-      <template v-else-if="menuActive">
-        <Editor v-model:value="menus[menuActive].content" :key="menuActive" />
-      </template>
-      <template v-if="menuActive">
-        <div class="flex justify-end py-4">
-          <el-popconfirm
-            title="是否确认清空内容?"
-            @confirm="menus[menuActive].content = ''"
-          >
-            <template #reference>
-              <el-button type="warning" plain>清空内容</el-button>
-            </template>
-          </el-popconfirm>
-          <el-button
-            type="primary"
-            plain
-            @click="
-              menuActive = 0;
-              menuChange(0, menus[0]);
-            "
-            >去预览</el-button
-          >
-        </div>
-        <div class="p-4 rounded bg-gray-50">
-          <div class="flex items-center space-x-2">
-            <span class="font-bold">系统建议:</span>
-            <el-input
-              v-model.trim="searchVal"
-              clearable
-              placeholder="请输入标题搜索"
-              class="w-fit"
-            ></el-input>
-            <el-button type="primary">搜索</el-button>
-          </div>
-          <div class="space-y-4 pt-6">
-            <el-collapse
-              v-model="collapseActive"
-              accordion
-              class="py-4"
-              @change="collapseChange"
-            >
-              <!-- v-for="(item, index) in menus[menuActive]?.articleList" -->
-              <div
-                v-for="(item, index) in filterArticleList"
-                :key="index"
-                class="bg-white px-4 py-2 rounded flex items-center"
-              >
-                <CirclePlusFilled
-                  class="w-6 cursor-pointer text-blue-500 mr-4"
-                  @click="addArticle(item)"
-                />
-
-                <el-collapse-item :name="index" class="flex-1">
-                  <template #title>
-                    <div class="font-bold">
-                      {{ item.label }}
-                    </div>
-                  </template>
-                  <div class="flex-1">
-                    <div class="text-gray-500">
-                      <div v-html="item.content"></div>
-                    </div>
-                  </div>
-                </el-collapse-item>
-              </div>
-            </el-collapse>
-            <!-- <el-collapse-item title="Consistency" name="1"></el-collapse-item> -->
-          </div>
-        </div>
-      </template>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import emptyImg from "@/assets/icon-empty-left.png";
-import LeftMenu from "./LeftMenu.vue";
-import { Search, CirclePlusFilled } from "@element-plus/icons-vue";
-
-import Editor from "@/components/Editor.vue";
-import { request, deduplicateArrayByKeys } from "@/utils";
-
-const getArticle = inject("getArticle");
-const getNodeRelationship = inject("getNodeRelationship");
-const getBatchNodeRelationships = inject("getBatchNodeRelationships");
-const parentState = inject("parentState");
-const diseaseMangeNode = inject("diseaseMangeNode");
-const updateStateValueForKey = inject("updateStateValueForKey");
-const menus = ref([]);
-watch(
-  () => menus.value,
-  () => {
-    updateStateValueForKey(
-      "personalizeInterventions",
-      menus.value
-        .filter(v => v.id)
-        .map(v => {
-          return {
-            id: v.id,
-            title: v.label,
-            content: v.content
-          };
-        })
-    );
-  },
-  {
-    deep: true
-  }
-);
-const menuActive = ref(0);
-
-const searchVal = ref("");
-const filterArticleList = computed(() =>
-  menus.value[menuActive.value].articleList.filter(v =>
-    v.label.includes(searchVal.value)
-  )
-);
-const waitDefaultAppend = [];
-const init = async () => {
-  const personalizeInterventions = parentState.value.personalizeInterventions;
-  let articleList = await getNodeRelationship(
-    diseaseMangeNode.value,
-    "干预方式"
-  );
-  articleList = articleList
-    .map(v => {
-      return {
-        id: v.mId,
-        label: v.mProperties.name,
-        articleId: v.mProperties["文章ID"]
-      };
-    })
-    .sort((a, b) => a.sort - b.sort);
-  let temp = await getBatchNodeRelationships(
-    articleList.map(v => v.id).join(),
-    "类别属于"
-  );
-  await Promise.all(
-    parentState.value.etiologies
-      .filter(v => v.id)
-      .map(async v => {
-        const data = await getNodeRelationship(v.id, "推荐干预方式");
-        waitDefaultAppend.push(
-          ...(data || []).map(v => {
-            return {
-              id: v.mId,
-              label: v.mProperties.name,
-              articleId: v.mProperties["文章ID"]
-            };
-          })
-        );
-      })
-  );
-  let classify = [];
-  temp.forEach(async v => {
-    let findClassify = classify.find(v2 => v2.id == v.mId);
-    // let findArticle = waitDefaultAppend.find(v2 => v.nId == v2.id)?.articleId || ''
-    // let appendContent = findArticle ? await getArticle(findArticle).content : ''
-    let appendContent = "";
-    if (findClassify) {
-      findClassify.articleList.push(articleList.find(v2 => v2.id == v.nId));
-      findClassify.content += appendContent;
-    } else {
-      classify.push({
-        id: v.mId,
-        label: v.mProperties.name,
-        title: v.mProperties.name,
-        content:
-          (personalizeInterventions.find(v2 => v2.id == v.mId)?.content || "") +
-          appendContent,
-        articleList: [articleList.find(v2 => v2.id == v.nId)],
-        sort: v.mProperties["排序"]
-      });
-    }
-  });
-  // temp = temp.map(v => {
-  //   return {
-  //     id: v.mId,
-  //     label: v.mProperties.name,
-  //     title: v.mProperties.name,
-  //     content: personalizeInterventions.find(v2 => v2.id == v.mId)?.content || "",
-  //     articleList: [],
-  //     sort: v.mProperties["排序"]
-  //   };
-  // }).forEach(v => {
-
-  // })
-
-  // .sort((a, b) => a.sort - b.sort)
-  // deduplicateArrayByKeys(, ['id'])
-  menus.value = classify.sort((a, b) => a.sort - b.sort);
-  menus.value = [{ label: "干预方案预览", fixed: true }, ...menus.value];
-  // console.log();
-  // menus.value = data
-  //   .map(v => {
-  //     return {
-  //       id: v.mId,
-  //       label: v.mProperties.name,
-  //       title: v.mProperties.name,
-  //       content: personalizeInterventions.find(v2 => v2.id == v.mId)?.content || "",
-  //       articleList: [],
-  //       sort: v.mProperties["排序"]
-  //     };
-  //   })
-  //   .sort((a, b) => a.sort - b.sort);
-  // menus.value = [{ label: "干预方案预览", fixed: true }, ...menus.value];
-};
-init();
-
-const menuChange = async (i, menu) => {
-  if (menu.id && !menu.articleList.length) {
-    const data = await getNodeRelationship(menu.id, "干预方式");
-    menu.articleList = (data || []).map(v => {
-      return {
-        id: v.mId,
-        label: v.mProperties.name,
-        articleId: v.mProperties["文章ID"],
-        content: ""
-      };
-    });
-  }
-  searchVal.value = "";
-};
-
-const collapseActive = ref();
-const collapseChange = async idx => {
-  if (
-    idx != undefined &&
-    !menus.value[menuActive.value].articleList[idx].content
-  ) {
-    const detail = await getArticle(
-      menus.value[menuActive.value]?.articleList[idx].articleId
-    );
-    menus.value[menuActive.value].articleList[idx].content = detail.content;
-  }
-};
-const addArticle = async item => {
-  if (!item.content) {
-    const detail = await getArticle(item.articleId);
-    item.content = detail.content;
-  }
-  menus.value[menuActive.value].content += item.content;
-};
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 70
src/views/healthManagement/healthPlan/LeftMenu.vue

@@ -1,70 +0,0 @@
-<template>
-  <div
-    class="bg-gray-50 w-1/6 min-w-[120px] max-w-[200px] h-full overflow-y-auto p-2"
-  >
-    <div
-      v-for="(item, index) in props.menus"
-      :key="index"
-      class="cursor-pointer my-1 py-4 px-2 relative flex items-center justify-between hover:bg-gray-100 rounded-lg"
-      :class="{
-        'text-gray-600': value != index,
-        'text-blue-500 bg-gray-200 hover:bg-gray-200': value == index,
-      }"
-      @click="menuClick(item, index)"
-    >
-      <div class="">
-        <div class="flex items-center">
-          <CaretRight class="transition-all" :class="value == index ? 'w-4' : 'w-0'" />
-          <span>{{ item.label }}</span>
-        </div>
-        <slot name="itemDesc" :item="item"></slot>
-      </div>
-      <div v-if="value == index" class="rounded bg-blue-500 h-5 w-1"></div>
-
-    </div>
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick
-} from "vue";
-
-import {
-  CaretRight
-} from "@element-plus/icons-vue";
-
-const props = defineProps({
-  menus: {
-    type: Array,
-    default: () => []
-  },
-  active: {
-    type: Number,
-    default: 0
-  }
-});
-const emit = defineEmits(["update:active", "change"]);
-const value = computed({
-  get() {
-    return props.active;
-  },
-  set(v) {
-    emit("update:active", v);
-  }
-});
-const menuClick = (item, index) => {
-  value.value = index
-  emit('change', value.value, item, index)
-}
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 87
src/views/healthManagement/healthPlan/NextFeedbackSetting.vue

@@ -1,87 +0,0 @@
-<template>
-  <div class="p-4">
-    <div class="rounded shadow-lg p-4">
-      <el-form label-position="top">
-        <el-form-item label="下次评估时间:" required>
-          <el-date-picker
-            v-model="date"
-            type="date"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            placeholder="请选择评估时间"
-          />
-        </el-form-item>
-        <el-form-item label="下次评估时期望达成效果:" required>
-          <Editor v-model:value="goals" />
-        </el-form-item>
-      </el-form>
-      <el-form-item>
-        <Auth value="healthManage">
-          <el-button type="primary" @click="save">保存并提交</el-button>
-        </Auth>
-      </el-form-item>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import Editor from "@/components/Editor.vue";
-import { request } from "@/utils";
-import { ElMessage } from "element-plus";
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-const [route, router] = [useRoute(), useRouter()];
-
-const parentState = inject("parentState");
-const updateStateValueForKey = inject("updateStateValueForKey");
-const date = ref(parentState.value.nextTime || "");
-const goals = ref(parentState.value.target || "");
-watch(
-  () => date.value,
-  () => {
-    updateStateValueForKey("nextTime", date.value);
-  }
-);
-watch(
-  () => goals.value,
-  () => {
-    updateStateValueForKey("target", goals.value);
-  }
-);
-
-const save = async () => {
-  const req = {
-    ...parentState.value
-  };
-  req.etiologies = req.etiologies.map(v => ({
-    id: v.id,
-    label: v.label,
-    type: v.type
-  }));
-  console.log(req);
-  // if (!req.effectId) {
-  //   return ElMessage.error('请选择管理效果')
-  // }
-  if (!req.nextTime) {
-    return ElMessage.error("请选择下次评估时间");
-  }
-  if (!req.target) {
-    return ElMessage.error("请填写下次评估时期望达成效果");
-  }
-  await request.post(`/dataService/healthManage/create`, req);
-  ElMessage.success("操作成功");
-  router.back();
-};
-</script>
-
-<style lang="scss" scoped></style>

+ 0 - 237
src/views/healthManagement/healthPlan/SituationAssessment.vue

@@ -1,237 +0,0 @@
-<template>
-  <div class="p-4 space-y-4 h-full overflow-y-auto">
-    <div class="border border-solid border-gray-100 rounded shadow-lg p-4">
-      <div class="space-y-4">
-        <div class="font-bold text-base">综合评估:</div>
-
-        <div class="space-y-2">
-          <span>临床诊断</span>
-          <div>
-
-            <div v-if="medicalHistory.length">
-              <el-tag
-                v-for="(t, tIdx) in medicalHistory"
-                :key="tIdx"
-                class="mr-1 mb-1"
-              >
-                <span class="inline-block align-middle">{{ t }} </span>
-              </el-tag>
-            </div>
-            <div v-else class="text-sm text-gray-500">暂无数据</div>
-          </div>
-        </div>
-        <div class="space-y-2">
-          <span>重大疾病风险评估</span>
-          <div>
-            <div v-if="highRiskDiseaseList.length">
-              <el-tag
-                v-for="(t, tIdx) in highRiskDiseaseList"
-                :key="tIdx"
-                class="mr-1 mb-1"
-              >
-                <span class="inline-block align-middle">{{ t.name }} </span>
-              </el-tag>
-            </div>
-
-            <div v-else class="text-sm text-gray-500">暂无有明显风险疾病</div>
-          </div>
-        </div>
-        <div class="space-y-2">
-          <span>功能医学分析</span>
-          <div>
-            <div v-if="etiologies.length">
-              <el-tag
-                v-for="(child, childIdx) in etiologies"
-                :key="childIdx"
-                class="mr-1 mb-1"
-                type="danger"
-                >{{ child.label }}</el-tag
-              >
-            </div>
-            <div v-else class="text-sm text-gray-500">暂未选择</div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="border border-solid border-gray-100 rounded shadow-lg p-4">
-      <el-form label-position="top">
-        <el-form-item
-          :label="
-            lastEvaluation
-              ? `健康综合评分(${dayjs(lastEvaluation.createdAt).format(
-                  'YYYY-MM-DD'
-                )}至${dayjs().format('YYYY-MM-DD')}):`
-              : '健康综合评分:'
-          "
-          required
-        >
-          <!-- <el-select v-model="evaluation" filterable @change="evaluationChange">
-            <el-option
-              v-for="(item, index) in situation"
-              :key="index"
-              :label="item.label"
-              :value="index"
-            ></el-option>
-          </el-select> -->
-          <div class="flex items-center">
-            <div class="w-[300px] mx-4">
-              <el-slider v-model="evaluation" @change="evaluationChange" />
-            </div>
-            <span class="text-gray-600">{{ evaluation }}</span>
-            <span class="text-gray-600 text-xs">分</span>
-          </div>
-        </el-form-item>
-      </el-form>
-    </div>
-    <!-- <div v-if="lastEvaluation" class="space-y-4">
-      <div class="border border-solid border-gray-100 rounded shadow-lg p-4">
-        <div class="space-y-4">
-          <div class="font-bold text-base">病因变化对比:</div>
-          <div class="">
-            <div class="text-gray-500 text-sm m-1">
-              上次({{
-                dayjs(lastEvaluation.createdAt).format("YYYY-MM-DD")
-              }})分析后的主要病因:
-            </div>
-            <el-tag
-              v-for="(tag, tagIdx) in lastEvaluation.etiologies"
-              :key="tagIdx"
-              size="large"
-              type="danger"
-              class="m-1"
-              >{{ tag.label }}</el-tag
-            >
-          </div>
-          <div class="">
-            <div class="text-gray-500 text-sm m-1">今天分析后的主要病因:</div>
-
-            <div v-if="etiologies.length">
-              <el-tag
-                v-for="(child, childIdx) in etiologies"
-                :key="childIdx"
-                class="m-1"
-                type="danger"
-                >{{ child.label }}</el-tag
-              >
-            </div>
-            <div v-else class="text-sm text-gray-500">暂未选择</div>
-          </div>
-        </div>
-      </div>
-      <div class="border border-solid border-gray-100 rounded shadow-lg p-4">
-        <div>
-          <div class="font-bold text-base">上次设定的期望达成目标:</div>
-          <div class="p-2 bg-gray-50 rounded">
-            <div v-html="lastEvaluation?.target"></div>
-          </div>
-        </div>
-      </div>
-      <div class="border border-solid border-gray-100 rounded shadow-lg p-4">
-        <div class="space-y-4">
-          <div class="font-bold text-base">上次制定的个性化干预方案:</div>
-          <div
-            v-for="(child, childIdx) in lastEvaluation.personalizeInterventions"
-            :key="childIdx"
-          >
-            <template v-if="child.content">
-              <div class="font-bold">{{ child.title }}:</div>
-              <div class="p-2 bg-gray-50 rounded">
-                <div v-html="child.content"></div>
-              </div>
-            </template>
-          </div>
-        </div>
-      </div>
-    </div> -->
-  </div>
-</template>
-
-<script setup>
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  inject,
-  onMounted,
-  provide,
-  defineAsyncComponent,
-  nextTick,
-  shallowRef
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-import dayjs from "dayjs";
-import { debounce, request } from "@/utils";
-
-const [route, router] = [useRoute(), useRouter()];
-const parentState = inject("parentState");
-const healthHistoryList = inject("healthHistoryList");
-const getNodes = inject("getNodes");
-const updateStateValueForKey = inject("updateStateValueForKey");
-const situation = ref([]);
-const evaluation = ref(parentState.value.score);
-
-const etiologies = computed(() => parentState.value.etiologies);
-const lastEvaluation = ref();
-
-const medicalHistory = shallowRef([]);
-const highRiskDiseaseList = shallowRef([]);
-const init = async () => {
-  const nodes = await getNodes({
-    tag: "管理效果"
-  });
-  situation.value = (nodes?.list || [])
-    .map(v => {
-      return {
-        id: v.id,
-        label: v.properties?.name,
-        sort: v.properties?.["程度"]
-      };
-    })
-    .sort((a, b) => a.sort - b.sort);
-
-  // if (healthHistoryList.value[0]) {
-  //   lastEvaluation.value = healthHistoryList.value[0];
-  //   console.log(lastEvaluation.value);
-  // }
-
-  const { data } = await request.get(
-    `/archivesService/mechanism/archives/portrait`,
-    {
-      params: {
-        archivesId: route.query.archivesId
-      }
-    }
-  );
-  medicalHistory.value = (data.list.find(v => v.sort == 4)?.list || [])
-    .map(v => v.list)
-    .flat()
-    .map(v => v.value)
-    .flat();
-
-  const { data: archivesData } = await request.get(
-    "/archivesService/mechanism/archives/detail",
-    {
-      params: {
-        archivesId: route.query?.archivesId
-      }
-    }
-  );
-  highRiskDiseaseList.value = archivesData.highRiskDiseaseList;
-};
-init();
-
-const evaluationChange = debounce(() => {
-  updateStateValueForKey("score", evaluation.value);
-}, 100);
-</script>
-
-<style lang="scss" scoped>
-::v-deep .el-slider__bar {
-  background: transparent;
-  // background-image: linear-gradient(to right, #ff5f6d, #ffb641, #42f57b);
-}
-::v-deep .el-slider__runway {
-  background-image: linear-gradient(to right, #ff5f6d, #ffb641, #42f57b);
-}
-</style>

+ 0 - 556
src/views/healthManagement/managementHealthPlan.vue

@@ -1,556 +0,0 @@
-<template>
-  <div>
-    <el-card shadow="never">
-      <el-row :gutter="10">
-        <el-col :span="18">
-          <el-row>
-            <el-select
-              multiple
-              v-model="state.query.peopleType"
-              placeholder="全部人群"
-              clearable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in peopleTypeList"
-                :label="item.label"
-                :value="item.value"
-                :key="item.value"
-              />
-            </el-select>
-            <div>
-              <el-date-picker
-                v-model="state.query.times"
-                type="daterange"
-                clearable
-                range-separator="至"
-                value-format="YYYY-MM-DD"
-                start-placeholder="开始时间"
-                end-placeholder="结束时间"
-              />
-            </div>
-            <div class="ml-2">
-              <el-input
-                v-model="state.query.value"
-                placeholder="请输入"
-                class="input-with-select"
-                clearable
-              >
-                <template #prepend>
-                  <el-select
-                    v-model="state.query.key"
-                    placeholder="请选择"
-                    style="width: 115px"
-                    clearable
-                  >
-                    <el-option label="用户" value="user" />
-                    <el-option label="第三方订单号" value="outTradeNo" />
-                  </el-select>
-                </template>
-                <template #append>
-                  <el-button :icon="Search" @click="onSearch">查询</el-button>
-                </template>
-              </el-input>
-            </div>
-            <el-button
-              type="primary"
-              link
-              class="ml-2"
-              @click="() => (state.visibleMore = !state.visibleMore)"
-              :icon="state.visibleMore ? ArrowUp : ArrowDown"
-              >{{ state.visibleMore ? "收起" : "展开" }}</el-button
-            >
-          </el-row>
-          <el-row class="mt-2" v-if="state.visibleMore">
-            <el-select
-              multiple
-              v-model="state.query.preventLevel"
-              placeholder="全部预防级别"
-              clearable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in levelList"
-                :label="item.label"
-                :value="item.value"
-                :key="item.value"
-              />
-            </el-select>
-            <el-select
-              multiple
-              v-model="state.query.confirmedDiseases"
-              placeholder="全部已确诊疾病"
-              filterable
-              clearable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in state.nodeList"
-                :key="item.id"
-                :label="item.properties?.name"
-                :value="item.id"
-              />
-            </el-select>
-
-            <el-select
-              multiple
-              v-model="state.query.highRiskDiseases"
-              placeholder="全部高风险疾病"
-              clearable
-              filterable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in state.nodeList"
-                :key="item.id"
-                :label="item.properties?.name"
-                :value="item.id"
-              />
-            </el-select>
-
-            <el-select
-              class="mr-2"
-              multiple
-              v-model="state.query.diseases"
-              placeholder="全部管理中的疾病"
-              clearable
-              filterable
-              style="width: 200px"
-            >
-              <el-option
-                v-for="item in state.nodeList"
-                :key="item.id"
-                :label="item.properties?.name"
-                :value="item.id"
-              />
-            </el-select>
-            <!-- <el-cascader
-              v-model="state.query.tagIds"
-              :props="selectProps"
-              clearable
-              placeholder="请选择标签"
-              @change="handleChange"
-              :options="state.tagCategoryList"
-            /> -->
-          </el-row>
-        </el-col>
-        <el-col class="text-right" :span="6">
-          <!-- <el-button
-            type="primary"
-            @click="state.visibleCurrentMonthBacklog = true"
-            >本月待办事项列表</el-button
-          > -->
-        </el-col>
-      </el-row>
-    </el-card>
-    <el-card shadow="never" class="mt-4">
-      <div>
-        <el-table :data="state.tableData" style="width: 100%" border>
-          <el-table-column prop="sn" label="档案号" width="100" />
-          <el-table-column prop="name" label="姓名" />
-          <el-table-column prop="gender" label="性别" width="60" />
-          <el-table-column prop="age" label="年龄" width="60" />
-          <el-table-column label="管理疾病名称">
-            <template #default="{ row }">
-              <div>
-                {{ row?.managementInfo?.disease }}
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="目前主要病因">
-            <template #default="{ row }">
-              <div v-if="row?.managementInfo?.etiologies?.length">
-                <el-tag
-                  v-for="(item, index) in row?.managementInfo?.etiologies"
-                  :key="index"
-                  class="mb-1 mr-1"
-                  type="danger"
-                  >{{ item.label }}</el-tag
-                >
-              </div>
-            </template>
-          </el-table-column>
-
-          <el-table-column label="目前健康综合评分">
-            <template #default="{ row }">
-              <div v-if="row?.managementInfo?.score">
-                <span
-                  :style="{
-                    color:
-                      healthManagementEffect[
-                        Math.floor(row?.managementInfo?.score / 25)
-                      ]
-                  }"
-                >
-                  <!-- {{ levelList[row?.managementInfo?.level].label }} -->
-                  {{ row?.managementInfo?.score }}
-                </span>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="评估时间"
-            :formatter="v => v?.managementInfo?.createdAt?.split(' ')[0]"
-          />
-          <el-table-column label="下阶段管理目标">
-            <template #default="{ row }">
-              <div class="max-h-[150px] overflow-y-auto">
-                <div v-html="row?.managementInfo?.target" />
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="下阶段评估时间">
-            <template #default="{ row }">
-              <div v-if="row.status">
-                <el-text tag="b">已暂停管理</el-text>
-              </div>
-              <div v-else>
-                <span
-                  v-if="
-                    moment().format('YYYY-MM-DD') ==
-                    row?.managementInfo?.nextTime?.split(' ')[0]
-                  "
-                  style="color: #67c23a"
-                >
-                  今天 ({{
-                    row?.managementInfo?.nextTime?.split(" ")[0]
-                  }})</span
-                >
-                <span
-                  v-else-if="
-                    moment().valueOf() >
-                    moment(
-                      row?.managementInfo?.nextTime?.split(' ')[0].valueOf()
-                    )
-                  "
-                  style="color: #f56c6c"
-                >
-                  超时{{
-                    Number(
-                      0 -
-                        timeDiffer(row?.managementInfo?.nextTime?.split(" ")[0])
-                    )
-                  }}天 ({{
-                    row?.managementInfo?.nextTime?.split(" ")[0]
-                  }})</span
-                >
-                <span v-else-if="!row?.managementInfo?.nextTime">-</span>
-                <span v-else
-                  >还剩{{
-                    timeDiffer(row?.managementInfo?.nextTime?.split(" ")[0])
-                  }}天({{
-                    row?.managementInfo?.nextTime?.split(" ")[0]
-                  }})</span
-                >
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column prop="age" label="操作">
-            <template #default="{ row }">
-              <Auth value="headlthManage:todoList:view">
-                <el-button type="primary" link @click="handleBacklog(row)"
-                  >待办事项</el-button
-                >
-              </Auth>
-
-              <el-button type="primary" link @click="handleManage(row)"
-                >管理</el-button
-              >
-            </template>
-          </el-table-column>
-        </el-table>
-
-        <el-pagination
-          class="justify-end mt-4"
-          :current-page="state.query.page"
-          :page-size="state.query.pageSize"
-          :total="state.total"
-          background
-          layout="total, prev, pager, next, jumper"
-          @current-change="
-            page => {
-              state.query.page = page;
-              getList();
-            }
-          "
-        />
-      </div>
-    </el-card>
-    <ComponentDialogBacklog
-      v-model:show="state.visibleBacklog"
-      type="preview"
-    />
-
-    <ComponentDialogCurrentMonthBacklog
-      v-model:show="state.visibleCurrentMonthBacklog"
-    />
-  </div>
-</template>
-<script lang="ts" setup>
-import { reactive, ref, watch } from "vue";
-import { Search, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-import { useRouter, useRoute } from "vue-router";
-import { request, timeDiffer } from "@/utils";
-const [route, router] = [useRoute(), useRouter()];
-import ComponentDialogBacklog from "./components/DialogBacklog.vue";
-import ComponentDialogCurrentMonthBacklog from "./components/DialogCurrentMonthBacklog.vue";
-import { manageLevel, healthManagementEffect } from "@/enums/managementPlan.ts";
-
-import type { CascaderProps } from "element-plus";
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-import moment from "moment";
-import { resolve } from "dns";
-const useManageProject = useManageProjectStoreHook();
-const state = reactive({
-  query: {
-    page: 1,
-    pageSize: 15,
-    peopleType: [],
-    preventLevel: [],
-    times: [],
-    value: "",
-    key: "",
-    confirmedDiseases: [], //  确诊疾病id多选,多个使用,隔开
-    highRiskDiseases: [], // 高风险疾病id多选,多个使用,隔开
-    diseases: [], // 多选疾病名称,多个使用,隔开
-    tagIds: []
-  },
-  total: 0,
-  nodeList: [],
-  tableData: [],
-  visibleBacklog: false,
-  rowData: {},
-  visibleMore: false,
-  tagCategoryList: [], // 标签类别
-  visibleCurrentMonthBacklog: false
-});
-const mergeArr = ["sn", "name", "gender", "age", " "];
-const mergeObj = {};
-const peopleTypeList = [
-  {
-    label: "有已确诊疾病人群",
-    value: 3
-  },
-  {
-    label: "有高风险疾病人群",
-    value: 1
-  },
-  {
-    label: "有正在服药人群",
-    value: 4
-  },
-  {
-    label: "有易感疾病基因携带人群",
-    value: 2
-  },
-  {
-    label: "有管理中的疾病人群",
-    value: 5
-  },
-  {
-    label: "无管理中的疾病人群",
-    value: 6
-  }
-];
-const levelList = manageLevel;
-const getList = () => {
-  let startTime = undefined;
-  let endTime = undefined;
-  let tagIds = [];
-  if (state.query?.times?.length) {
-    [startTime, endTime] = state.query.times;
-  } else {
-    [startTime, endTime] = [undefined, undefined];
-  }
-  if (state.query.tagIds?.length) {
-    tagIds = state.query.tagIds?.map(v => v[1])?.join(",");
-  } else {
-    tagIds = undefined;
-  }
-  request
-    .get("/platformApi/dataService/healthManage/paginate", {
-      params: {
-        key: state.query.key,
-        value: state.query.value,
-        page: state.query.page,
-        pageSize: state.query.pageSize,
-        diseases: state.query.diseases?.join(","),
-        highRiskDiseases: state.query.highRiskDiseases?.join(","),
-        confirmedDiseases: state.query.confirmedDiseases?.join(","),
-        crowds: state.query.peopleType.join(","),
-        levels: state.query.preventLevel.join(","),
-        start: startTime,
-        end: endTime,
-        tagIds: tagIds
-      }
-    })
-    .then(resp => {
-      state.tableData = transformData(resp.data.list);
-      state.total = resp.data.total;
-      getSpanArr(state.tableData);
-
-      console.log(state.tableData);
-    });
-};
-
-const getNodeList = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 9999,
-        tag: "可管理"
-      }
-    })
-    .then(resp => {
-      state.nodeList = resp.data.list;
-    });
-};
-const onSearch = () => {
-  state.query.page = 1;
-  getList();
-};
-const handleBacklog = row => {
-  state.visibleBacklog = true;
-  state.rowData = row;
-  useManageProject?.SET_CURRENT_ARCHIVES(row.sn);
-};
-const handleManage = row => {
-  // router.push("/archives/assess");
-
-  useManageProject?.SET_CURRENT_ARCHIVES(row.sn);
-  router.push({
-    path: "/healthManagement/plan/detail",
-    query: {
-      archivesId: row.sn,
-      type: "health"
-    }
-  });
-};
-const getSpanArr = data => {
-  mergeArr.forEach((key, index1) => {
-    let count = 0; // 用来记录需要合并行的起始位置
-    mergeObj[key] = []; // 记录每一列的合并信息
-    data.forEach((item, index) => {
-      // index == 0表示数据为第一行,直接 push 一个 1
-      if (index === 0) {
-        mergeObj[key].push(1);
-      } else {
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
-        if (
-          item[key] === data[index - 1][key] &&
-          item["sn"] === data[index - 1]["sn"]
-        ) {
-          mergeObj[key][count] += 1;
-          mergeObj[key].push(0);
-        } else {
-          // 如果当前行和上一行其值不相等
-          count = index; // 记录当前位置
-          mergeObj[key].push(1); // 重新push 一个 1
-        }
-      }
-    });
-  });
-};
-// 默认接受四个值 { 当前行的值, 当前列的值, 行的下标, 列的下标 }
-const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
-  // 判断列的属性
-  if (mergeArr.indexOf(column.property) !== -1) {
-    // 判断其值是不是为0
-    if (mergeObj[column.property][rowIndex]) {
-      return [mergeObj[column.property][rowIndex], 1];
-    } else {
-      // 如果为0则为需要合并的行
-      return [0, 0];
-    }
-  }
-};
-const transformData = data => {
-  const transformedData = [];
-
-  data.forEach(item => {
-    if (item.managements.length) {
-      item.managements.forEach((management, index) => {
-        transformedData.push({
-          ...item,
-          managementInfo: management
-        });
-      });
-    } else {
-      transformedData.push({
-        ...item,
-        managementInfo: {}
-      });
-    }
-  });
-  return transformedData;
-};
-const getTagCategoryList = () => {
-  request.get("/tagService/mechanism/tagCategory/list").then(resp => {
-    state.tagCategoryList = resp.data.list.map(v => {
-      return {
-        ...v,
-        value: v.id,
-        label: v.name
-      };
-    });
-  });
-};
-const getTagList = id => {
-  if (!id) return;
-  return new Promise(resolve => {
-    request
-      .get(`/tagService/mechanism/tag/list?categoryId=${id}&type=1`)
-      .then(resp => {
-        resolve(resp.data.list);
-      });
-  });
-};
-const selectProps: CascaderProps = {
-  lazy: true,
-  multiple: true,
-  lazyLoad: async (node, resolve) => {
-    const { value } = node;
-    let list = await getTagList(value);
-    console.log(list);
-    list = list?.map(v => {
-      return {
-        ...v,
-        value: v.id,
-        label: v.name,
-        leaf: true
-      };
-    });
-    console.log("list", list);
-
-    // Invoke `resolve` callback to return the child nodes data and indicate the loading is finished.
-    resolve(list);
-  }
-};
-watch(
-  () => [
-    state.query.peopleType,
-    state.query.preventLevel,
-    state.query.confirmedDiseases,
-    state.query.highRiskDiseases,
-    state.query.diseases,
-    state.query.tagIds
-  ],
-  () => {
-    console.log("监听成功");
-
-    onSearch();
-  },
-  { deep: true }
-);
-const initData = () => {
-  getNodeList();
-  getList();
-  getTagCategoryList();
-};
-initData();
-</script>

+ 0 - 685
src/views/healthManagement/managementPlan.vue

@@ -1,685 +0,0 @@
-<template>
-  <div>
-    <el-card shadow="never">
-      <el-row :gutter="10">
-        <el-col :span="18">
-          <el-row>
-            <el-select
-              multiple
-              v-model="state.query.channelIds"
-              placeholder="全部渠道"
-              clearable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in channelList"
-                :label="item.name"
-                :value="item.id"
-                :key="item.id"
-              />
-            </el-select>
-            <el-cascader
-              v-model="state.query.groupIds"
-              :props="selectGroupsProps"
-              clearable
-              placeholder="全部管理分组"
-              :options="state.groups"
-              class="mr-2"
-            />
-            <div class="mr-2">
-              <el-date-picker
-                v-model="state.query.times"
-                type="daterange"
-                clearable
-                range-separator="至"
-                value-format="YYYY-MM-DD"
-                start-placeholder="开始时间"
-                end-placeholder="结束时间"
-              />
-            </div>
-
-            <!-- <el-cascader
-              v-model="state.query.tagIds"
-              :props="selectProps"
-              clearable
-              placeholder="请选择标签"
-              :options="state.tagCategoryList"
-            /> -->
-            <el-select
-              v-model="state.query.tagIds"
-              placeholder="全部标签"
-              filterable
-              clearable
-              multiple
-            >
-              <el-option
-                v-for="item in state.tagCategoryList"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
-            <el-button type="primary" class="ml-2" @click="onSearch"
-              >查询</el-button
-            >
-            <el-button type="primary" plain @click="onReset">重置</el-button>
-
-            <!-- <el-button
-              type="primary"
-              link
-              class="ml-2"
-              @click="() => (state.visibleMore = !state.visibleMore)"
-              :icon="state.visibleMore ? ArrowUp : ArrowDown"
-              >{{ state.visibleMore ? "收起" : "展开" }}</el-button
-            > -->
-          </el-row>
-          <!-- <el-row class="mt-2" v-if="state.visibleMore">
-            <el-select
-              multiple
-              v-model="state.query.preventLevel"
-              placeholder="全部预防级别"
-              clearable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in levelList"
-                :label="item.label"
-                :value="item.value"
-                :key="item.value"
-              />
-            </el-select>
-            <el-select
-              multiple
-              v-model="state.query.confirmedDiseases"
-              placeholder="全部已确诊疾病"
-              filterable
-              clearable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in state.nodeList"
-                :key="item.id"
-                :label="item.properties?.name"
-                :value="item.id"
-              />
-            </el-select>
-
-            <el-select
-              multiple
-              v-model="state.query.highRiskDiseases"
-              placeholder="全部高风险疾病"
-              clearable
-              filterable
-              style="width: 200px"
-              class="mr-2"
-            >
-              <el-option
-                v-for="item in state.nodeList"
-                :key="item.id"
-                :label="item.properties?.name"
-                :value="item.id"
-              />
-            </el-select>
-
-            <el-select
-              class="mr-2"
-              multiple
-              v-model="state.query.diseases"
-              placeholder="全部管理中的疾病"
-              clearable
-              filterable
-              style="width: 200px"
-            >
-              <el-option
-                v-for="item in state.nodeList"
-                :key="item.id"
-                :label="item.properties?.name"
-                :value="item.id"
-              />
-            </el-select>
-          </el-row> -->
-        </el-col>
-        <el-col class="text-right" :span="6">
-          <!-- <el-button
-            type="primary"
-            @click="state.visibleCurrentMonthBacklog = true"
-            >本月待办事项列表</el-button
-          > -->
-          <div class="ml-2">
-            <el-input
-              v-model="state.query.value"
-              placeholder="请输入"
-              class="input-with-select"
-              clearable
-            >
-              <template #prepend>
-                <el-select
-                  v-model="state.query.key"
-                  placeholder="请选择"
-                  style="width: 115px"
-                  clearable
-                >
-                  <el-option label="档案号" value="archive_id" />
-                  <el-option label="姓名" value="name" />
-                </el-select>
-              </template>
-              <template #append>
-                <el-button :icon="Search" @click="onSearch">查询</el-button>
-              </template>
-            </el-input>
-          </div>
-        </el-col>
-      </el-row>
-    </el-card>
-    <el-card shadow="never" class="mt-4">
-      <div>
-        <el-table :data="state.tableData" style="width: 100%" border>
-          <el-table-column label="用户信息" width="150">
-            <template #default="{ row }">
-              <div>
-                <el-text>{{ row.sn }}</el-text>
-                <div class="mt-1">{{ row.name }}</div>
-              </div>
-              <div class="flex items-center">
-                <el-button link type="primary" v-if="row.gender == '男'"
-                  >男</el-button
-                >
-                <el-button type="danger" v-else link>女</el-button>
-                <el-text class="">,{{ row.age }}岁</el-text>
-              </div>
-              <!-- <div class="mt-2 flex items-center">
-                <el-text>年龄:</el-text>
-                <el-text tag="b">{{ row.age }}岁</el-text>
-              </div> -->
-              <div class="mt-1 flex items-center">
-                <div style="font-size: 12px">
-                  <span v-for="(channel, index) in row.channels" :key="index"
-                    >{{ channel }}
-                    <span v-if="index < row.channels.length - 1">、</span>
-                  </span>
-                </div>
-              </div>
-            </template>
-          </el-table-column>
-
-          <el-table-column label="标签">
-            <template #default="{ row }">
-              <el-scrollbar>
-                <div v-if="row?.tags?.length" style="width: 100%">
-                  <el-space wrap>
-                    <el-tag
-                      class="mr-2"
-                      v-for="(tag, index) in row.tags"
-                      :key="tag + index"
-                      >{{ tag }}</el-tag
-                    >
-                  </el-space>
-                </div>
-              </el-scrollbar>
-            </template>
-          </el-table-column>
-
-          <el-table-column label="管理分组">
-            <template #default="{ row }">
-              <div>
-                <el-tag class="mr-2" v-if="row?.managementInfo?.levelName">{{
-                  formatLevel(row.managementInfo?.levelName)
-                }}</el-tag>
-                {{ row?.managementInfo?.groupName }}
-              </div>
-            </template>
-          </el-table-column>
-
-          <el-table-column label="现存主要问题">
-            <template #default="{ row }">
-              <div v-if="row?.managementInfo?.focus?.length">
-                <el-tag
-                  v-for="(item, index) in row?.managementInfo?.focus"
-                  :key="index"
-                  class="mr-2"
-                  >{{ item }}</el-tag
-                >
-              </div>
-            </template>
-          </el-table-column>
-
-          <el-table-column label="目前健康状况">
-            <template #default="{ row }">
-              <div v-if="row?.managementInfo?.level">
-                <span
-                  :style="{
-                    color: managementEffect[row?.managementInfo?.effect['程度']]
-                  }"
-                >
-                  {{ row?.managementInfo?.effect?.name }}
-                </span>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column
-            label="评估时间"
-            :formatter="v => v?.managementInfo?.createdAt?.split(' ')[0]"
-          />
-          <el-table-column
-            label="下阶段管理目标"
-            :formatter="v => v?.managementInfo?.target"
-          />
-          <el-table-column label="下阶段评估时间">
-            <template #default="{ row }">
-              <div v-if="row.status">
-                <el-text tag="b">已暂停管理</el-text>
-              </div>
-              <div v-else>
-                <span
-                  v-if="
-                    moment().format('YYYY-MM-DD') ==
-                    row?.managementInfo?.nextTime?.split(' ')[0]
-                  "
-                  style="color: #67c23a"
-                >
-                  今天 ({{
-                    row?.managementInfo?.nextTime?.split(" ")[0]
-                  }})</span
-                >
-                <span
-                  v-else-if="
-                    moment().valueOf() >
-                    moment(
-                      row?.managementInfo?.nextTime?.split(' ')[0].valueOf()
-                    )
-                  "
-                  style="color: #f56c6c"
-                >
-                  超时{{
-                    Number(
-                      0 -
-                        timeDiffer(row?.managementInfo?.nextTime?.split(" ")[0])
-                    )
-                  }}天 ({{
-                    row?.managementInfo?.nextTime?.split(" ")[0]
-                  }})</span
-                >
-                <span v-else-if="!row?.managementInfo?.nextTime">-</span>
-                <span v-else
-                  >还剩{{
-                    timeDiffer(row?.managementInfo?.nextTime?.split(" ")[0])
-                  }}天({{
-                    row?.managementInfo?.nextTime?.split(" ")[0]
-                  }})</span
-                >
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column prop="" label="操作">
-            <template #default="{ row }">
-              <Auth value="headlthManage:todoList:view">
-                <el-button type="primary" link @click="handleBacklog(row)"
-                  >待办事项</el-button
-                >
-              </Auth>
-              <Auth value="healthManage">
-                <el-button type="primary" link @click="handleManage(row)"
-                  >管理</el-button
-                >
-              </Auth>
-            </template>
-          </el-table-column>
-        </el-table>
-
-        <el-pagination
-          class="justify-end mt-4"
-          :current-page="state.query.page"
-          :page-size="state.query.pageSize"
-          :total="state.total"
-          background
-          layout="total, prev, pager, next, jumper"
-          @current-change="
-            page => {
-              state.query.page = page;
-              getList();
-            }
-          "
-        />
-      </div>
-    </el-card>
-    <ComponentDialogBacklog
-      v-model:show="state.visibleBacklog"
-      type="preview"
-    />
-
-    <ComponentDialogCurrentMonthBacklog
-      v-model:show="state.visibleCurrentMonthBacklog"
-    />
-  </div>
-</template>
-<script lang="ts" setup>
-import { reactive, ref, watch } from "vue";
-import { Search, ArrowUp, ArrowDown } from "@element-plus/icons-vue";
-import { useRouter, useRoute } from "vue-router";
-import { request, timeDiffer } from "@/utils";
-const [route, router] = [useRoute(), useRouter()];
-import ComponentDialogBacklog from "./components/DialogBacklog.vue";
-import ComponentDialogCurrentMonthBacklog from "./components/DialogCurrentMonthBacklog.vue";
-import ComponentCopy from "@/components/Copy/index.vue";
-import {
-  manageLevel,
-  managementEffect,
-  formatLevel
-} from "@/enums/managementPlan.ts";
-
-import type { CascaderProps } from "element-plus";
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-import moment from "moment";
-const useManageProject = useManageProjectStoreHook();
-const state = reactive({
-  query: {
-    page: 1,
-    pageSize: 15,
-    peopleType: [],
-    preventLevel: [],
-    channelIds: [],
-    groupIds: [],
-    times: [],
-    value: "",
-    key: "",
-    confirmedDiseases: [], //  确诊疾病id多选,多个使用,隔开
-    highRiskDiseases: [], // 高风险疾病id多选,多个使用,隔开
-    diseases: [], // 多选疾病名称,多个使用,隔开
-    tagIds: []
-  },
-  total: 0,
-  nodeList: [],
-  tableData: [],
-  visibleBacklog: false,
-  rowData: {},
-  visibleMore: false,
-  tagCategoryList: [], // 标签类别
-  groups: [],
-  visibleCurrentMonthBacklog: false
-});
-const mergeArr = ["sn", "name", "gender", "age", " "];
-const mergeObj = {};
-const peopleTypeList = [
-  {
-    label: "有已确诊疾病人群",
-    value: 3
-  },
-  {
-    label: "有高风险疾病人群",
-    value: 1
-  },
-  {
-    label: "有正在服药人群",
-    value: 4
-  },
-  {
-    label: "有易感疾病基因携带人群",
-    value: 2
-  },
-  {
-    label: "有管理中的疾病人群",
-    value: 5
-  },
-  {
-    label: "无管理中的疾病人群",
-    value: 6
-  }
-];
-const channelList = ref([]);
-const levelList = manageLevel;
-const getChannelList = () => {
-  request
-    .get("archivesService/mechanism/channel/paginate?key=&page=1&pageSize=9999")
-    .then(res => {
-      channelList.value = res.data.list;
-    });
-};
-const getList = () => {
-  let startTime = undefined;
-  let endTime = undefined;
-  let tagIds = [];
-  let groupIds = undefined;
-  if (state.query?.times?.length) {
-    [startTime, endTime] = state.query.times;
-  } else {
-    [startTime, endTime] = [undefined, undefined];
-  }
-  if (state.query.tagIds?.length) {
-    tagIds = state.query.tagIds?.join(",");
-  } else {
-    tagIds = undefined;
-  }
-  if (state.query.groupIds?.length) {
-    groupIds = state.query.groupIds?.map(v => v[1])?.join(",");
-  } else {
-    groupIds = undefined;
-  }
-  request
-    .get("/platformApi/dataService/diseaseManage/paginate", {
-      params: {
-        key: state.query.key,
-        value: state.query.value,
-        page: state.query.page,
-        pageSize: state.query.pageSize,
-        channelIds: state.query.channelIds?.join(","),
-        groupIds: groupIds,
-        // levels: state.query.preventLevel.join(","),
-        start: startTime,
-        end: endTime,
-        tagIds: tagIds
-      }
-    })
-    .then(resp => {
-      state.tableData = transformData(resp.data.list);
-      state.total = resp.data.total;
-      getSpanArr(state.tableData);
-
-      console.log(state.tableData);
-    });
-};
-
-const getNodeList = () => {
-  request
-    .get("/platformApi/graphService/open/node/paginate", {
-      params: {
-        pageSize: 9999,
-        tag: "可管理"
-      }
-    })
-    .then(resp => {
-      state.nodeList = resp.data.list;
-    });
-};
-const onSearch = () => {
-  state.query.page = 1;
-  getList();
-};
-const onReset = () => {
-  state.query.channelIds = [];
-  state.query.groupIds = [];
-  state.query.tagIds = [];
-  state.query.times = [];
-  state.query.value = "";
-  state.query.key = "";
-  onSearch();
-};
-const handleBacklog = row => {
-  state.visibleBacklog = true;
-  state.rowData = row;
-  useManageProject?.SET_CURRENT_ARCHIVES(row.sn);
-};
-const handleManage = row => {
-  // router.push("/archives/assess");
-
-  useManageProject?.SET_CURRENT_ARCHIVES(row.sn);
-  router.push(`/healthManagement/plan/detail?archivesId=${row.sn}`);
-};
-const getSpanArr = data => {
-  mergeArr.forEach((key, index1) => {
-    let count = 0; // 用来记录需要合并行的起始位置
-    mergeObj[key] = []; // 记录每一列的合并信息
-    data.forEach((item, index) => {
-      // index == 0表示数据为第一行,直接 push 一个 1
-      if (index === 0) {
-        mergeObj[key].push(1);
-      } else {
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
-        if (
-          item[key] === data[index - 1][key] &&
-          item["sn"] === data[index - 1]["sn"]
-        ) {
-          mergeObj[key][count] += 1;
-          mergeObj[key].push(0);
-        } else {
-          // 如果当前行和上一行其值不相等
-          count = index; // 记录当前位置
-          mergeObj[key].push(1); // 重新push 一个 1
-        }
-      }
-    });
-  });
-};
-// 默认接受四个值 { 当前行的值, 当前列的值, 行的下标, 列的下标 }
-const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
-  // 判断列的属性
-  if (mergeArr.indexOf(column.property) !== -1) {
-    // 判断其值是不是为0
-    if (mergeObj[column.property][rowIndex]) {
-      return [mergeObj[column.property][rowIndex], 1];
-    } else {
-      // 如果为0则为需要合并的行
-      return [0, 0];
-    }
-  }
-};
-const transformData = data => {
-  const transformedData = [];
-
-  data.forEach(item => {
-    if (item.managements.length) {
-      item.managements.forEach((management, index) => {
-        transformedData.push({
-          ...item,
-          managementInfo: management
-        });
-      });
-    } else {
-      transformedData.push({
-        ...item,
-        managementInfo: {}
-      });
-    }
-  });
-  return transformedData;
-};
-const getTagCategoryList = () => {
-  request
-    .get("dataService/schemeManage/tag/paginate?page=1&pageSize=999")
-    .then(resp => {
-      state.tagCategoryList = resp.data.list;
-    });
-};
-const getTagList = id => {
-  if (!id) return;
-  return new Promise(resolve => {
-    request
-      .get(`/tagService/mechanism/tag/list?categoryId=${id}&type=1`)
-      .then(resp => {
-        resolve(resp.data.list);
-      });
-  });
-};
-const getGroups = () => {
-  request.get("dataService/schemeManage/diseaseManageLevels").then(resp => {
-    state.groups = resp.data?.map(v => {
-      return {
-        ...v,
-        value: v.id,
-        label: v.title
-      };
-    });
-  });
-};
-const getDiseaseManageGroup = value => {
-  if (!value) return;
-  return new Promise(resolve => {
-    request
-      .get(`dataService/schemeManage/diseaseManageGroup/paginate`, {
-        params: {
-          levelId: value,
-          pageSize: 999
-        }
-      })
-      .then(resp => {
-        resolve(resp.data.list);
-      });
-  });
-};
-
-const selectProps: CascaderProps = {
-  lazy: true,
-  multiple: true,
-  lazyLoad: async (node, resolve) => {
-    const { value } = node;
-    let list = await getTagList(value);
-    console.log(list);
-    list = list?.map(v => {
-      return {
-        ...v,
-        value: v.id,
-        label: v.name,
-        leaf: true
-      };
-    });
-    console.log("list", list);
-
-    // Invoke `resolve` callback to return the child nodes data and indicate the loading is finished.
-    resolve(list);
-  }
-};
-const selectGroupsProps: CascaderProps = {
-  lazy: true,
-  multiple: true,
-  lazyLoad: async (node, resolve) => {
-    const { value } = node;
-    let list = await getDiseaseManageGroup(value);
-    list = list?.map(v => {
-      return {
-        ...v,
-        value: v.id,
-        label: v.name,
-        leaf: true
-      };
-    });
-    resolve(list);
-  }
-};
-// watch(
-//   () => [
-//     state.query.peopleType,
-//     state.query.preventLevel,
-//     state.query.confirmedDiseases,
-//     state.query.highRiskDiseases,
-//     state.query.diseases,
-//     state.query.tagIds
-//   ],
-//   () => {
-//     console.log("监听成功");
-
-//     onSearch();
-//   },
-//   { deep: true }
-// );
-const initData = () => {
-  getNodeList();
-  getList();
-  getGroups();
-  getTagCategoryList();
-  getChannelList();
-};
-initData();
-</script>

+ 0 - 169
src/views/healthManagement/messageNotification.vue

@@ -1,169 +0,0 @@
-<template>
-  <div>
-    <el-card shadow="never">
-      <template #header>
-        <el-row class="flex items-center">
-          <h4 class="mr-4">待办事项短信通知</h4>
-          <el-switch
-            v-model="status"
-            style="--el-switch-on-color: #13ce66"
-            :active-value="1"
-            :inactive-value="0"
-            @change="handleChangeStatus"
-          />
-        </el-row>
-        <span class="text-yellow-600 text-sm"
-          >开启后,系统将在每周末自动统计用户下周的待办事项,如果有,将会给用户发送短信通知消息</span
-        >
-      </template>
-      <div>
-        <el-row>
-          <div class="text-right w-full">
-            <el-space wrap>
-              <el-date-picker
-                v-model="filter.time"
-                type="datetimerange"
-                start-placeholder="开始时间"
-                end-placeholder="结束时间"
-              />
-              <el-select v-model="filter.status" placeholder="请选择">
-                <el-option label="全部状态" :value="-1" />
-                <el-option
-                  v-for="item in statusList"
-                  :key="item.v"
-                  :label="item.k"
-                  :value="item.v"
-                />
-              </el-select>
-
-              <SearchArchivesSelect
-                style="width: 100%"
-                v-model="filter.archiveId"
-                placeholder="请选择档案"
-              />
-              <el-button type="primary" :icon="Search" @click="onSearch"
-                >搜索</el-button
-              >
-            </el-space>
-          </div>
-        </el-row>
-        <el-table :data="state.list" style="width: 100%" class="mt-10">
-          <el-table-column prop="archiveId" label="短信通知对象档案号" />
-          <el-table-column prop="archiveName" label="短信通知对象姓名" />
-          <el-table-column prop="noticeTime" label="短信通知时间">
-            <template #default="{ row }">
-              <el-text>{{ row.noticeTime || "-" }}</el-text>
-            </template>
-          </el-table-column>
-          <el-table-column prop="remark" label="短信通知状态">
-            <template #default="{ row }">
-              <el-text :class="statusList[row.status - 1]?.c"
-                >{{ statusList[row.status - 1]?.k || "-" }}
-              </el-text>
-            </template>
-          </el-table-column>
-          <el-table-column prop="noticeTime" label="备注信息">
-            <template #default="{ row }">
-              <el-text>{{ row.remark }}</el-text>
-            </template>
-          </el-table-column>
-        </el-table>
-      </div>
-    </el-card>
-  </div>
-</template>
-<script setup>
-import SearchArchivesSelect from "@/components/Archives/SearchArchivesSelect.vue";
-
-import { request } from "@/utils";
-import { Search, Plus } from "@element-plus/icons-vue";
-import { ElMessage, ElMessageBox } from "element-plus";
-import moment from "moment";
-
-import { reactive } from "vue";
-import { ref } from "vue";
-
-const status = ref(0);
-const filter = reactive({
-  time: "",
-  status: -1,
-  page: 1,
-  pageSize: 15,
-  archiveId: ""
-});
-const state = reactive({
-  list: [],
-  total: 0
-});
-const statusList = ref([
-  {
-    k: "发送成功",
-    v: 1,
-    c: "text-green-600"
-  },
-  {
-    k: "发送失败",
-    v: 2,
-    c: "text-red-600"
-  },
-  {
-    k: "用户接收成功",
-    v: 3,
-    c: "text-green-600"
-  },
-  {
-    k: "用户接收失败",
-    v: 4,
-    c: "text-red-600"
-  }
-]);
-const onSearch = () => {
-  filter.page = 1;
-  getList();
-};
-const handleChangeStatus = () => {
-  ElMessageBox.confirm(
-    status.value
-      ? `确定要开启吗?开启后,系统将于${moment().format(
-          "YYYY年MM月DD日"
-        )}开始,每个周末统计所有用户下周的待办事项,并依次发送短信通知`
-      : "确定要关闭吗?关闭后系统不会再给用户发送待办事项提醒短信",
-    "",
-    {
-      distinguishCancelAndClose: true,
-      confirmButtonText: "确定",
-      cancelButtonText: "取消"
-    }
-  )
-    .then(async () => {
-      await request.post("dataService/diseaseManage/todo/notice/status", {
-        status: status.value
-      });
-      ElMessage.success("操作成功");
-      getNoticeStatus();
-    })
-    .catch(err => {
-      status.value = status.value ? 0 : 1;
-    });
-};
-const getList = () => {
-  request
-    .get("dataService/diseaseManage/todo/notice/paginate", {
-      params: filter
-    })
-    .then(resp => {
-      state.list = resp.data.list;
-      state.total = resp.data.total;
-    });
-};
-const getNoticeStatus = () => {
-  request.get("dataService/diseaseManage/todo/notice/status", {}).then(resp => {
-    status.value = resp.data.status;
-  });
-};
-const initData = () => {
-  getList();
-  getNoticeStatus();
-};
-initData();
-</script>

+ 0 - 463
src/views/healthManagement/planDetail.vue

@@ -1,463 +0,0 @@
-<template>
-  <div class="page-plan-detail h-full flex">
-    <div
-      class="w-1/5 min-w-[320px] p-4 space-y-2 text-sm h-full overflow-y-auto flex flex-nowrap flex-col"
-    >
-      <div class="shadow-sm bg-white p-4">
-        <div class="flex items-start">
-          <div class="w-12 h-12">
-            <img
-              :src="archivesInfo?.gender == 1 ? man : woman"
-              round
-              class="w-12 h-12 rounded-full mr-4"
-            />
-          </div>
-          <div class="flex-1 pl-4 space-y-2">
-            <p>{{ archivesInfo.name }}</p>
-            <div class="flex items-center my-1">
-              <div class="flex items-center mr-4">
-                <img src="@/assets/icon-gender.png" alt="" class="w-5 h-5" />
-                <span class="text-sm text-gray-700">{{
-                  archivesInfo.gender == 1 ? "男" : "女"
-                }}</span>
-              </div>
-              <div class="flex items-center my-1">
-                <img src="@/assets/icon-birthday.png" alt="" class="w-5 h-5" />
-                <span class="text-sm text-gray-700"
-                  >{{ formatAge(archivesInfo.birthday) }}岁</span
-                >
-              </div>
-            </div>
-            <div class="flex items-center">
-              <span>档案号:</span>
-              <span>{{ archivesInfo.id }}</span>
-              <CopyDocument
-                v-if="archivesInfo.id"
-                class="w-4 text-blue-500 cursor-copy ml-1"
-                v-copy="archivesInfo.id"
-              />
-            </div>
-            <div class="flex items-center">
-              <span
-                >联系方式:{{
-                  archivesInfo.accounts.find(v => v.type === 1)?.account
-                }}</span
-              >
-
-              <CopyDocument
-                v-if="archivesInfo?.accounts?.find(v => v.type === 1)?.account"
-                class="w-4 text-blue-500 cursor-copy ml-1"
-                v-copy="archivesInfo.accounts.find(v => v.type === 1)?.account"
-              />
-            </div>
-          </div>
-        </div>
-
-        <div class="flex items-center mt-4">
-          <Auth value="healthManage">
-            <el-button type="primary" @click="uploadDialogVisible = true"
-              >上传数据</el-button
-            >
-          </Auth>
-          <el-button type="primary" @click="visibleBacklog = true"
-            >待办事件管理</el-button
-          >
-        </div>
-      </div>
-      <div class="shadow-sm bg-white">
-        <div
-          class="border-0 border-b border-solid border-gray-100 p-2 flex items-center justify-between"
-        >
-          用户标签
-          <Auth value="healthManage:userTag">
-            <el-button
-              type="primary"
-              link
-              :icon="Edit"
-              @click="visibleTags = true"
-              >编辑</el-button
-            >
-          </Auth>
-        </div>
-        <div class="p-2">
-          <el-tag
-            v-for="(item, index) in archivesTags"
-            :key="index"
-            class="m-1"
-            >{{ item.name }}</el-tag
-          >
-          <span
-            v-if="!archivesInfo?.tags?.length"
-            class="text-xs m-1 text-gray-400"
-            >暂无数据</span
-          >
-        </div>
-      </div>
-      <div class="shadow-sm bg-white">
-        <div class="border-0 border-b border-solid border-gray-100 p-2">
-          已确诊疾病
-        </div>
-        <div class="p-2">
-          <el-tag
-            v-for="(item, index) in recommendValues.medicalHistory"
-            :key="index"
-            class="m-1"
-            type="danger"
-            >{{ item.name }}</el-tag
-          >
-          <span
-            v-if="!recommendValues.medicalHistory.length"
-            class="text-xs m-1 text-gray-400"
-            >暂无数据</span
-          >
-        </div>
-      </div>
-      <div class="shadow-sm bg-white">
-        <div class="border-0 border-b border-solid border-gray-100 p-2">
-          高风险疾病
-        </div>
-        <div class="p-2">
-          <el-tag
-            v-for="(item, index) in highRiskDiseaseList"
-            :key="index"
-            type="danger"
-            class="m-1"
-            >{{ item.name }}</el-tag
-          >
-          <span
-            v-if="!highRiskDiseaseList.length"
-            class="text-xs m-1 text-gray-400"
-            >暂无数据</span
-          >
-        </div>
-      </div>
-      <div class="shadow-sm bg-white">
-        <div class="border-0 border-b border-solid border-gray-100 p-2">
-          易感疾病基因携带
-        </div>
-        <div class="p-2">
-          <el-tag
-            v-for="(item, index) in recommendValues.susceptibilityGene"
-            :key="index"
-            class="m-1"
-            type="warning"
-            >{{ item.name }}</el-tag
-          >
-          <span
-            v-if="!recommendValues.susceptibilityGene.length"
-            class="text-xs m-1 text-gray-400"
-            >暂无数据</span
-          >
-        </div>
-      </div>
-      <div class="shadow-sm bg-white">
-        <div class="border-0 border-b border-solid border-gray-100 p-2">
-          正在用药
-        </div>
-        <div class="p-2">
-          <el-tag
-            v-for="(item, index) in recommendValues.medicationStatus"
-            :key="index"
-            class="m-1"
-            >{{ item.name }}</el-tag
-          >
-          <span
-            v-if="!recommendValues.medicationStatus.length"
-            class="text-xs m-1 text-gray-400"
-            >暂无数据</span
-          >
-        </div>
-      </div>
-      <div class="shadow-sm bg-white flex-1">
-        <div
-          v-for="(menu, menuIdx) in menus"
-          :key="menuIdx"
-          class="flex items-center justify-between py-3 px-4 border-0 border-b border-solid border-gray-100 cursor-pointer text-sm hover:bg-gray-50"
-          :class="{ 'bg-gray-50 text-blue-500': curMenu === menu.key }"
-          @click="curMenu = menu.key"
-        >
-          <span>{{ menu.label }}</span>
-          <ArrowRight class="w-4" />
-        </div>
-      </div>
-    </div>
-    <div class="flex-1 overflow-y-auto relative m-4 ml-0 bg-white shadow-sm">
-      <component
-        v-if="menus.find(v => v.key === curMenu)"
-        :is="menus.find(v => v.key === curMenu)?.component"
-        :needHorizontal="true"
-        :nodeId="'4:b8fbfa26-3437-4bbb-8349-96abd14851ea:635'"
-        :list="evaluateDetail"
-      />
-      <!-- <component :is="ManagementPlan"></component> -->
-      <!-- <ManagementPlan v-else></ManagementPlan> -->
-    </div>
-    <UploadDataDialog v-model:visible="uploadDialogVisible" />
-    <ComponentDialogBacklog v-model:show="visibleBacklog" />
-    <ComponentDialogEditTags
-      v-model:show="visibleTags"
-      :id="archivesInfo.id"
-      @success="getArchiveTags"
-    />
-  </div>
-</template>
-<script setup>
-import { Search, Plus, Edit, Delete } from "@element-plus/icons-vue";
-import {
-  computed,
-  watch,
-  markRaw,
-  ref,
-  reactive,
-  onMounted,
-  provide,
-  defineAsyncComponent
-} from "vue";
-import { useRoute, useRouter } from "vue-router";
-// import ManagementPlan from "./components/ManagementPlan.vue";
-import {
-  CopyDocument,
-  Fold,
-  ArrowLeft,
-  ArrowRight
-} from "@element-plus/icons-vue";
-import man from "@/assets/icon-man.png";
-import woman from "@/assets/icon-woman.png";
-import {
-  formatAge,
-  parseJsonData,
-  request,
-  transformDataExpand
-} from "@/utils";
-
-import UploadDataDialog from "@/views/dataCenter/components/UploadDataDialog.vue";
-import ComponentDialogBacklog from "./components/DialogBacklog.vue";
-import ComponentDialogEditTags from "./components/DialogEditTags.vue";
-import FollowUpData from "./components/FollowUpData.vue";
-const uploadDialogVisible = ref(false);
-const visibleBacklog = ref(false);
-
-const RiskWarningReport = defineAsyncComponent(() =>
-  import("./components/RiskWarningReport.vue")
-);
-const archives = defineAsyncComponent(() =>
-  import("./components/PlanArchives.vue")
-);
-const checkData = defineAsyncComponent(() =>
-  import("./components/PlanCheckData.vue")
-);
-const HealthManagementPlan = defineAsyncComponent(() =>
-  import("./components/HealthManagementPlan.vue")
-);
-const planManage = defineAsyncComponent(() =>
-  import("./components/ManagementPlan.vue")
-);
-const AssessmentHistory = defineAsyncComponent(() =>
-  import("./components/AssessmentHistory.vue")
-);
-const LastTimeContent = defineAsyncComponent(() =>
-  import("./components/LastTimeContent.vue")
-);
-const IndicatorTrends = defineAsyncComponent(() =>
-  import("./components/IndicatorTrends.vue")
-);
-const DiseaseVisit = defineAsyncComponent(() =>
-  import("./components/DiseaseVisit.vue")
-);
-// const FollowUpData = defineAsyncComponent(() => {
-//   import("./components/FollowUpData.vue");
-// });
-const route = useRoute();
-const router = useRouter();
-const evaluateDetail = ref([]);
-const commonMenu = [
-  {
-    label: "重大疾病风险预警报告",
-    key: "RiskWarningReport",
-    component: RiskWarningReport
-  },
-  {
-    label: "档案信息",
-    key: "archives",
-    component: archives
-  },
-  {
-    label: "检查数据",
-    key: "checkData",
-    component: checkData
-  },
-  {
-    label: "回访数据",
-    key: "DiseaseVisit",
-    component: DiseaseVisit
-  },
-
-  {
-    label: "随访数据",
-    key: "FollowUpData",
-    component: FollowUpData
-  }
-];
-const menus = markRaw([
-  ...[
-    route.query.type == "health"
-      ? {
-          label: "健康管理",
-          key: "HealthManagementPlan",
-          component: HealthManagementPlan
-        }
-      : {
-          label: "管理计划",
-          key: "planManage",
-          component: planManage
-        }
-  ],
-  ...commonMenu
-  // {
-  //   label: "评估历史记录",
-  //   key: "AssessmentHistory",
-  //   component: AssessmentHistory
-  // },
-  // {
-  //   label: "上次设定的管理内容",
-  //   key: "LastTimeContent",
-  //   component: LastTimeContent
-  // },
-  // {
-  //   label: "关键指标趋势",
-  //   key: "IndicatorTrends",
-  //   component: IndicatorTrends
-  // },
-]);
-const visibleTags = ref(false);
-const archivesInfo = ref({
-  id: "",
-  name: "",
-  avatar: "",
-  gender: 0,
-  birthday: "",
-  mainArchivesId: "",
-  accounts: [],
-  tags: []
-});
-const archivesTags = ref([]);
-const defaultArchivesId = ref(route.query?.archivesId);
-provide("defaultArchivesId", defaultArchivesId);
-const highRiskDiseaseList = ref([]);
-const recommendValues = ref({
-  medicalHistory: [],
-  medicationStatus: [],
-  susceptibilityGene: []
-});
-
-const getArchiveTags = () => {
-  request
-    .get(
-      `dataService/schemeManage/tag/archive?archiveId=${defaultArchivesId.value}`
-    )
-    .then(resp => {
-      archivesTags.value = resp.data || [];
-    });
-};
-const getArchivesDetail = async () => {
-  const { data } = await request.get(
-    "/archivesService/mechanism/archives/detail",
-    {
-      params: {
-        archivesId: route.query?.archivesId
-      }
-    }
-  );
-  archivesInfo.value = data.detail;
-  highRiskDiseaseList.value = data.highRiskDiseaseList;
-  recommendValues.value = data.recommendValues;
-  // if (data.recommendValues) {
-  //   ["medicalHistory", "medicationStatus", "susceptibilityGene"].forEach(
-  //     key => {
-  //       if (data.recommendValues[key]) {
-  //         const { returnAnswer } = data.recommendValues[key];
-  //         if (returnAnswer) {
-  //           if (returnAnswer.groupAnswers) {
-
-  //           } else {
-
-  //           }
-  //         }
-  //       }
-  //     }
-  //   );
-  // }
-};
-getArchivesDetail();
-getArchiveTags();
-provide("refreshArchives", getArchivesDetail);
-
-const getArchivesReport = async () => {
-  const { data } = await request.get(
-    `/idcService/mechanism/medicalData/compareReport/detail`,
-    {
-      params: {
-        archivesId: route.query?.archivesId
-      }
-    }
-  );
-  compareReportDetail.value = data.detail;
-  compareSuggestion.value = data.detail.suggestion;
-  if (data.detail?.data) {
-    horizontalData.value = data.detail.data;
-  }
-  if (data.latestMedicalDataReport) {
-    resultRawJson.value = parseJsonData(
-      data.latestMedicalDataReport.resultRawJson
-    );
-  }
-};
-const getEvaluateDetail = () => {
-  request
-    .get("/platformApi/dataService/diseaseManage/detail", {
-      params: {
-        archiveId: route.query?.archivesId
-      }
-    })
-    .then(resp => {
-      const response = resp.data;
-
-      evaluateDetail.value = transformDataExpand(response, "histories");
-    });
-};
-const resultRawJson = ref();
-const horizontalData = ref();
-const compareReportDetail = ref();
-const compareSuggestion = ref();
-provide("resultRawJson", resultRawJson);
-provide("latestResultRawJson", resultRawJson);
-provide("horizontalData", horizontalData);
-provide("compareReportDetail", compareReportDetail);
-provide("compareSuggestion", compareSuggestion);
-const curMenu = ref();
-const initData = () => {
-  getArchivesReport();
-  getEvaluateDetail();
-  curMenu.value =
-    route.query.type || route.query.type == "health"
-      ? "HealthManagementPlan"
-      : "planManage";
-};
-initData();
-</script>
-
-<style lang="scss">
-.el-scrollbar__view {
-  height: 100%;
-  .main-content.page-plan-detail {
-    margin: 0;
-  }
-}
-.page-plan-detail {
-  overflow: hidden;
-  .data-container {
-    height: calc(100% - 48px);
-    width: 100%;
-  }
-}
-</style>

+ 0 - 627
src/views/healthManagement/todoList.vue

@@ -1,627 +0,0 @@
-<template>
-  <div>
-    <el-card title="" v-model="dialogVisible" :show-close="false" fullscreen>
-      <template #header>
-        <el-card>
-          <div>
-            <el-row :gutter="10">
-              <el-col :span="16" class="flex items-center">
-                事项期望完成时间:
-                <el-date-picker
-                  v-model="state.query.times"
-                  type="daterange"
-                  range-separator="-"
-                  start-placeholder="开始时间"
-                  end-placeholder="完成时间"
-                  value-format="YYYY-MM-DD"
-                  :shortcuts="shortcuts"
-                  :clearable="false"
-                />
-                <el-select
-                  v-model="state.query.type"
-                  placeholder="全部事项类型"
-                  filterable
-                  class="ml-2"
-                >
-                  <el-option label="全部事项类型" :value="-1" />
-                  <el-option
-                    v-for="item in state.typeList"
-                    :key="item.value"
-                    :label="item.key"
-                    :value="item.value"
-                  />
-                </el-select>
-                <el-select
-                  v-model="state.query.status"
-                  placeholder="全部完成状态"
-                  filterable
-                  class="ml-2"
-                >
-                  <el-option label="全部状态" :value="-1" />
-                  <el-option
-                    v-for="item in state.statusList"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  />
-                </el-select>
-              </el-col>
-              <el-col :span="8">
-                <div class="ml-2 flex items-center text-right">
-                  <el-input
-                    v-model="state.query.value"
-                    placeholder="请输入"
-                    class="input-with-select"
-                    clearable
-                  >
-                    <template #prepend>
-                      <el-select
-                        v-model="state.query.key"
-                        placeholder="请选择"
-                        style="width: 115px"
-                        clearable
-                      >
-                        <el-option label="档案号" value="archive_id" />
-                        <el-option label="姓名" value="name" />
-                      </el-select>
-                    </template>
-                    <template #append>
-                      <div class="flex">
-                        <el-button :icon="Search" @click="onSearch"
-                          >查询</el-button
-                        >
-                      </div>
-                    </template>
-                  </el-input>
-                  <el-button class="ml-2" type="info" plain @click="onRefresh"
-                    >重置</el-button
-                  >
-
-                  <!-- <el-button
-                    class="ml-10"
-                    type="danger"
-                    plain
-                    @click="dialogVisible = false"
-                    >关闭</el-button
-                  > -->
-                </div>
-              </el-col>
-            </el-row>
-          </div>
-        </el-card>
-      </template>
-
-      <el-card shadow="never" class="mt-4">
-        <div>
-          <el-table :data="state.tableData" style="width: 100%" border>
-            <el-table-column prop="sn" label="档案号" width="100" />
-            <el-table-column label="待办事项类型" width="140">
-              <template #default="{ row }">
-                <div>
-                  {{ row.name }}
-                  <div class="text-sm" style="font-size: 12px">
-                    {{ row.gender }},{{ row.age }}岁
-                  </div>
-                </div>
-              </template>
-            </el-table-column>
-
-            <!-- <el-table-column prop="name" label="姓名" width="100" />
-            <el-table-column prop="gender" label="性别" width="60" />
-            <el-table-column prop="age" label="年龄" width="60" /> -->
-            <el-table-column label="待办事项类型" width="140">
-              <template #default="{ row }">
-                <div
-                  class="todo-tag"
-                  :style="`border: 1px solid ${
-                    state.constType[row.todoInfo?.type]?.color
-                  }; color: ${state.constType[row.todoInfo?.type]?.color}`"
-                >
-                  {{ state.constType[row.todoInfo?.type]?.name }}
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column prop="theme" label="事项主题">
-              <template #default="{ row }">
-                <div>{{ row.todoInfo.theme }}</div>
-              </template>
-            </el-table-column>
-
-            <el-table-column prop="content" label="事项内容">
-              <template #default="{ row }">
-                <div v-if="row.todoInfo.type == 2">
-                  <el-space wrap>
-                    <div v-if="row.todoInfo?.content?.questions?.length">
-                      随访问卷
-                    </div>
-                    <div v-if="row.todoInfo?.content?.healthGuidance">
-                      随访健康指导
-                    </div>
-                  </el-space>
-                </div>
-                <div v-else-if="row.todoInfo.type == 0">
-                  {{ row.todoInfo.content }}
-                </div>
-                <div v-else>
-                  <el-space wrap>
-                    <div v-for="item in row.todoInfo.content" :key="item.id">
-                      <el-tag plain> {{ item.properties.name }}</el-tag>
-                    </div>
-                  </el-space>
-                </div>
-              </template>
-            </el-table-column>
-
-            <el-table-column label="事项期望完成时间" width="200">
-              <template #default="{ row }">
-                <div class="flex items-center">
-                  <el-text
-                    v-if="row.todoInfo?.startDate === row.todoInfo?.endDate"
-                    >{{ row.todoInfo?.startDate }}</el-text
-                  >
-                  <el-text v-else>
-                    {{ row.todoInfo?.startDate }} 至
-                    {{ row.todoInfo?.endDate }}
-                  </el-text>
-
-                  <!-- <el-tag>{{
-                      state.frequencyType[row.todoInfo?.frequencyType]
-                    }}</el-tag> -->
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column label="事项完成情况">
-              <template #default="{ row }">
-                <div class="flex items-center">
-                  <template
-                    v-if="row.todoInfo?.startDate !== row.todoInfo?.endDate"
-                  >
-                    <el-tag type="success" class="mr-2 mt-2">
-                      {{ row.todoInfo.statusMap?.completed }}次已完成</el-tag
-                    >
-                    <el-tag type="info" class="mr-2 mt-2"
-                      >{{ row.todoInfo.statusMap?.incomplete }}次未完成</el-tag
-                    >
-                    <el-tag class="mr-2 mt-2"
-                      >{{ row.todoInfo.statusMap?.todo }}次待完成</el-tag
-                    >
-                  </template>
-                  <template v-else>
-                    <div class="flex items-center">
-                      <el-tag
-                        type="success"
-                        v-if="row.todoInfo.statusMap?.completed"
-                        class="mr-2 mt-2"
-                      >
-                        已完成</el-tag
-                      >
-                      <el-tag
-                        type="info"
-                        v-if="row.todoInfo.statusMap?.incomplete"
-                        class="mr-2 mt-2"
-                        >未完成</el-tag
-                      >
-                      <el-tag
-                        v-if="row.todoInfo.statusMap?.todo"
-                        class="mr-2 mt-2"
-                        >待完成</el-tag
-                      >
-                      <div
-                        v-if="!row.todoInfo?.statusMap?.completed"
-                        class="pl-2 mt-2"
-                      >
-                        <el-tag
-                          v-if="!timeDiffer(row?.todoInfo?.endDate)"
-                          type="success"
-                          class="mr-2"
-                          >今天</el-tag
-                        >
-                        <el-tag
-                          v-if="timeDiffer(row?.todoInfo?.endDate) < 0"
-                          type="danger"
-                          class="mr-2"
-                          >超时{{
-                            Number(0 - timeDiffer(row?.todoInfo?.endDate))
-                          }}天</el-tag
-                        >
-                        <div v-else>
-                          <el-tag
-                            class="mr-2"
-                            v-if="timeDiffer(row?.todoInfo?.endDate)"
-                            >{{
-                              timeDiffer(row?.todoInfo?.endDate)
-                            }}天后</el-tag
-                          >
-                        </div>
-                      </div>
-                    </div>
-                  </template>
-                  <el-text style="font-size: 11px" class="mt-2">{{
-                    row.todoInfo.comment
-                  }}</el-text>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column prop="age" label="操作" width="100">
-              <template #default="{ row }">
-                <el-button type="primary" link @click="handleBacklog(row)"
-                  >事项处理</el-button
-                >
-                <!-- <el-button type="primary" link @click="handleManage(row)"
-                    >管理</el-button
-                  > -->
-              </template>
-            </el-table-column>
-          </el-table>
-
-          <el-pagination
-            class="justify-end mt-4"
-            :current-page="state.query.page"
-            :page-size="state.query.pageSize"
-            :total="state.total"
-            background
-            layout="total, prev, pager, next, jumper"
-            @current-change="
-              page => {
-                state.query.page = page;
-                getList();
-              }
-            "
-          />
-        </div>
-      </el-card>
-
-      <ComponentDialogBacklog
-        v-model:show="state.visibleBacklog"
-        type="preview"
-        :complateTime="state.rowData.todoInfo?.startDate"
-        @success="getList()"
-      />
-    </el-card>
-  </div>
-</template>
-<script lang="ts" setup>
-import { reactive, computed, defineProps, defineEmits, onMounted } from "vue";
-import { Search } from "@element-plus/icons-vue";
-import { useRouter, useRoute } from "vue-router";
-import { request, timeDiffer } from "@/utils";
-const [route, router] = [useRoute(), useRouter()];
-import moment from "moment";
-import ComponentDialogBacklog from "./components/DialogBacklog.vue";
-
-import { useManageProjectStoreHook } from "@/store/modules/manageProject";
-import { useUserStoreHook } from "@/store/modules/user";
-
-const useManageProject = useManageProjectStoreHook();
-const props = defineProps({
-  show: {
-    type: Boolean,
-    default: false
-  }
-});
-const initStart = moment().startOf("isoWeek");
-const initEnd = moment().endOf("isoWeek");
-
-const state = reactive({
-  query: {
-    page: 1,
-    pageSize: 15,
-    times: [
-      moment(initStart).format("YYYY-MM-DD"),
-      moment(initEnd).format("YYYY-MM-DD")
-    ],
-    value: "",
-    key: "",
-    type: -1,
-    status: -1
-  },
-  rowData: {},
-  total: 0,
-  tableData: [],
-  constType: [
-    {
-      name: "其他事项",
-      color: "#6CAD1F"
-    },
-    {
-      name: "复查",
-      color: "#FC40FF"
-    },
-    {
-      name: "随访",
-      color: "#5EBCFB"
-    },
-    {
-      name: "日常监测",
-      color: "#F56C6C"
-    }
-  ],
-  frequencyType: ["每天事项", "每周事项", "每月事项", "指定日期事项"],
-  typeList: [
-    {
-      key: "复查",
-      value: 1
-    },
-    {
-      key: "随访",
-      value: 2
-    },
-    {
-      key: "日常监测",
-      value: 3
-    },
-
-    {
-      key: "其他",
-      value: 0
-    }
-
-    // {
-    //   key: "检查",
-    //   value: 4
-    // },
-    // {
-    //   key: "回访",
-    //   value: 5
-    // }
-  ],
-  statusList: {
-    0: {
-      label: "未完成",
-      value: 0
-    },
-    1: {
-      label: "待完成",
-      value: 1
-    },
-
-    2: {
-      label: "已完成",
-      value: 2
-    }
-  },
-  visibleBacklog: false
-});
-const mergeArr = ["sn", "name", "gender", "age"];
-const mergeObj = {};
-const emits = defineEmits(["update:show"]);
-
-const shortcuts = [
-  {
-    text: "本周",
-    value: () => {
-      const end = new Date();
-      const start = new Date();
-      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-      return [initStart, initEnd];
-    }
-  },
-  {
-    text: "本月",
-    value: () => {
-      return [
-        moment().startOf("month").format("YYYY-MM-DD"),
-        moment().endOf("month").format("YYYY-MM-DD")
-      ];
-    }
-  },
-  {
-    text: "上个月",
-    value: () => {
-      return [
-        moment().subtract(1, "months").startOf("month").format("YYYY-MM-DD"),
-        moment().subtract(1, "months").endOf("month").format("YYYY-MM-DD")
-      ];
-    }
-  },
-  {
-    text: "上三个月",
-    value: () => {
-      return [
-        moment().subtract(3, "months").startOf("month").format("YYYY-MM-DD"),
-        moment().startOf("month").format("YYYY-MM-DD")
-      ];
-    }
-  },
-  {
-    text: "上六个月",
-    value: () => {
-      return [
-        moment().subtract(6, "months").startOf("month").format("YYYY-MM-DD"),
-        moment().startOf("month").format("YYYY-MM-DD")
-      ];
-    }
-  },
-  {
-    text: "下个月",
-    value: () => {
-      return [
-        moment().add(1, "months").startOf("month").format("YYYY-MM-DD"),
-        moment().add(1, "months").endOf("month").format("YYYY-MM-DD")
-      ];
-    }
-  },
-  {
-    text: "下三个月",
-    value: () => {
-      return [
-        moment().startOf("month").format("YYYY-MM-DD"),
-        moment().add(3, "months").startOf("month").format("YYYY-MM-DD")
-      ];
-    }
-  },
-  {
-    text: "下六个月",
-
-    value: () => {
-      return [
-        moment().startOf("month").format("YYYY-MM-DD"),
-        moment().add(6, "months").startOf("month").format("YYYY-MM-DD")
-      ];
-    }
-  }
-];
-
-const dialogVisible = computed({
-  get() {
-    return props.show;
-  },
-  set(n) {
-    emits("update:show", n);
-  }
-});
-
-onMounted(() => {
-  initData();
-});
-const getSpanArr = data => {
-  mergeArr.forEach((key, index1) => {
-    let count = 0; // 用来记录需要合并行的起始位置
-    mergeObj[key] = []; // 记录每一列的合并信息
-    data.forEach((item, index) => {
-      // index == 0表示数据为第一行,直接 push 一个 1
-      if (index === 0) {
-        mergeObj[key].push(1);
-      } else {
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
-        if (
-          item[key] === data[index - 1][key] &&
-          item["sn"] === data[index - 1]["sn"]
-        ) {
-          mergeObj[key][count] += 1;
-          mergeObj[key].push(0);
-        } else {
-          // 如果当前行和上一行其值不相等
-          count = index; // 记录当前位置
-          mergeObj[key].push(1); // 重新push 一个 1
-        }
-      }
-    });
-  });
-};
-// 默认接受四个值 { 当前行的值, 当前列的值, 行的下标, 列的下标 }
-const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
-  // 判断列的属性
-  if (mergeArr.indexOf(column.property) !== -1) {
-    // 判断其值是不是为0
-    if (mergeObj[column.property][rowIndex]) {
-      return [mergeObj[column.property][rowIndex], 1];
-    } else {
-      // 如果为0则为需要合并的行
-      return [0, 0];
-    }
-  }
-};
-
-const transformData = data => {
-  if (!data) return [];
-  const transformedData = [];
-
-  data.forEach(item => {
-    if (!item.scheduleStatistics) {
-      item.scheduleStatistics = [];
-    }
-
-    if (item?.scheduleStatistics?.length) {
-      item.scheduleStatistics.forEach((info, index) => {
-        transformedData.push({
-          ...item,
-          todoInfo: info
-        });
-      });
-    } else {
-      transformedData.push({
-        ...item,
-        todoInfo: {}
-      });
-    }
-  });
-  return transformedData;
-};
-
-const getList = () => {
-  if (!state.query?.times.length) return;
-  const [startDate, endDate] = state.query.times;
-  request
-    .get("dataService/schedule/archive/todoDuration", {
-      params: {
-        startDate,
-        endDate,
-        type: state.query.type,
-        status: state.query.status,
-        key: state.query.key,
-        value: state.query.value,
-        page: state.query.page,
-        pageSize: state.query.pageSize
-      }
-    })
-    .then(resp => {
-      state.tableData = transformData(resp?.data?.list);
-      state.total = resp?.data?.total;
-      getSpanArr(state.tableData);
-    });
-};
-const initData = () => {
-  getList();
-};
-const onSearch = () => {
-  state.query.page = 1;
-  getList();
-};
-const onRefresh = () => {
-  state.query = {
-    page: 1,
-    pageSize: 15,
-    times: [
-      // moment().startOf("month").format("YYYY-MM-DD"),
-      // moment().endOf("month").format("YYYY-MM-DD")
-      moment(initStart).format("YYYY-MM-DD"),
-      moment(initEnd).format("YYYY-MM-DD")
-    ],
-    value: "",
-    key: "",
-    type: -1,
-    status: -1
-  };
-  initData();
-};
-const handleBacklog = row => {
-  state.visibleBacklog = true;
-  state.rowData = row;
-  useManageProject.SET_CURRENT_ARCHIVES(row.sn);
-};
-const handleManage = row => {
-  const profile = useUserStoreHook()?.profile as any;
-  console.log("profile", profile);
-  if (!profile?.nickname) {
-    return;
-  }
-  const permissions = profile?.permissions;
-  if (profile?.isSuper == 1 || permissions.includes("archives:managePlan")) {
-    return router.push(
-      `/healthManagement/plan/detail?archivesId=${row.sn}&type=DiseaseVisit`
-    );
-  }
-  if (permissions.includes("archives:managePlanHealth")) {
-    useManageProject?.SET_CURRENT_ARCHIVES(row.sn);
-    router.push({
-      path: "/healthManagement/plan/detail",
-      query: {
-        archivesId: row.sn,
-        type: "health"
-      }
-    });
-  }
-  return;
-  router.push(
-    `/healthManagement/plan/detail?archivesId=${row.sn}&type=DiseaseVisit`
-  );
-};
-</script>
-<style lang="scss" scoped>
-.todo-tag {
-  display: inline-block;
-  padding: 2px 10px;
-  border-radius: 4px;
-}
-</style>