WXL (wul)
7 天以前 ffa22cc18c75c0a73a3fd987e2b62fbf55316db2
测试完成
已重命名1个文件
已修改23个文件
已添加2个文件
已复制3个文件
2020 ■■■■ 文件已修改
dist (2).zip 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Assistant/index.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/CallButton/index.vue 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/StatisticsCards/index.vue 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/index.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/sms.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sipService.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Satisfaction/sfstatistics/IndicatorStatistics.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Satisfaction/sfstatistics/index.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/discharge/index.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/operation/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/record/TracingInfo/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/record/detailpage/index copy.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/record/detailpage/index.vue 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/record/physical/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/tasklist/index.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/questionnaire/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/questionnaire/smsConfig/index.vue 1037 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/outsideChainwtnew.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/patient/patient/index.vue 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/patient/propaganda/QuestionnaireTask.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/patient/propaganda/particty.vue 131 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/repositoryai/templateku/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/sfstatistics/percentage/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
随访外链.zip 补丁 | 查看 | 原始文档 | blame | 历史
随访外链通用.zip 补丁 | 查看 | 原始文档 | blame | 历史
随访通用.zip 补丁 | 查看 | 原始文档 | blame | 历史
dist (2).zip
Binary files differ
src/components/Assistant/index.vue
@@ -152,17 +152,76 @@
                  d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"
                />
              </svg>
              <!-- âœ… æ–°å¢žçŸ­ä¿¡å›¾æ ‡ -->
              <svg
                v-else-if="action.icon === 'IconMessageSquare'"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
              >
                <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
                <line x1="8" y1="9" x2="16" y2="9" />
                <line x1="8" y1="13" x2="14" y2="13" />
                <line x1="8" y1="17" x2="12" y2="17" />
              </svg>
            </div>
            <div class="action-label">{{ action.label }}</div>
          </div>
        </div>
      </div>
    </transition>
    <!-- çŸ­ä¿¡å‘送对话框 -->
    <el-dialog
      title="短信发送"
      :visible.sync="smsDialogVisible"
      width="500px"
      :close-on-click-modal="false"
      append-to-body
    >
      <el-form ref="smsForm" :model="smsForm" label-width="100px">
        <el-form-item label="患者名称">
          <el-input v-model="smsForm.sendname" readonly></el-input>
        </el-form-item>
        <el-form-item label="年龄">
          <el-input v-model="smsForm.age" readonly></el-input>
        </el-form-item>
        <el-form-item label="电话">
          <el-input v-model="smsForm.telcode" readonly></el-input>
        </el-form-item>
        <el-form-item label="科室">
          <el-input v-model="smsForm.deptname" readonly></el-input>
        </el-form-item>
        <el-form-item label="病区">
          <el-input
            v-model="smsForm.leavehospitaldistrictname"
            readonly
          ></el-input>
        </el-form-item>
        <el-form-item label="短信内容">
          <el-input
            type="textarea"
            :rows="4"
            v-model="smsContent"
            placeholder="请输入短信内容..."
            maxlength="500"
            show-word-limit
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="smsDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="sendSms" :loading="smsLoading">
          ç¡®è®¤å‘送
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { getCurrentUserServiceSubtaskCount } from "@/api/AiCentre/index";
import { sendMsg } from "@/api/AiCentre/index";
export default {
  name: "FloatBall",
@@ -210,6 +269,17 @@
      hideTimer: null,
      updateTime: "",
      roles: null,
      // çŸ­ä¿¡å‘送对话框
      // smsDialogVisible: false,
      smsLoading: false, // âœ… æ–°å¢žåŠ è½½çŠ¶æ€
      smsContent: "",
      smsForm: {
        sendname: "",
        age: "",
        telcode: "",
        deptname: "",
        leavehospitaldistrictname: "",
      },
      // ç»Ÿè®¡æ•°æ®
      statsItems: [
        {
@@ -269,12 +339,12 @@
          icon: "IconPhone",
          url: "/followvisit/particty?type=1&serviceType=2",
        },
        // {
        //   id: 'chat',
        //   label: '在线聊天',
        //   icon: 'IconMessageCircle',
        //   url: '/chat'
        // }
        {
          id: "sendSms", // âœ… æ–°å¢žçŸ­ä¿¡å‘送
          label: "短信发送",
          icon: "IconMessageSquare",
          action: "openSmsDialog", // æ ‡è®°ä¸ºå¼¹æ¡†æ“ä½œ
        },
      ],
    };
  },
@@ -283,8 +353,35 @@
    totalUnread() {
      return this.statsItems.reduce((sum, item) => sum + item.unread, 0);
    },
    // âœ… Vuex åŒå‘绑定
    smsDialogVisible: {
      get() {
        return this.$store.state.sms.smsDialogVisible;
  },
      set(val) {
        if (!val) {
          this.$store.dispatch("sms/closeSmsDialog");
        }
      },
    },
  },
  watch: {
    // âœ… ç›‘听 Vuex å¯¹è¯æ¡†çŠ¶æ€
    "$store.state.sms.smsDialogVisible"(val) {
      if (val) {
        const patientData = this.$store.state.sms.patientData;
        this.smsForm = { ...patientData };
        this.smsContent = this.$store.state.sms.smsTemplate || "";
        // å±•开悬浮球
        if (!this.isExpanded) {
          this.isExpanded = true;
          this.isHidden = false;
          clearTimeout(this.hideTimer);
        }
      }
    },
  },
  mounted() {
    this.roles = this.$store.state.user.roles;
    this.loadPosition();
@@ -424,6 +521,15 @@
    },
    handleActionClick(action) {
      // å¦‚果是短信发送操作,打开对话框
      console.log(action);
      if (action.action === "openSmsDialog") {
        this.openSmsDialog();
        return;
      }
      // åŽŸæœ‰é€»è¾‘ä¿æŒä¸å˜
      console.log(this.roles, "this.roles");
      if (
        action.url &&
@@ -435,7 +541,53 @@
        this.$modal.msgError("非管理员用户暂无创建任务权限");
      }
    },
    // æ‰“开短信发送对话框
    openSmsDialog() {
      // ä»Žæ‚¬æµ®çƒå†…部打开时,清空表单(因为没有选中患者)
      this.$store.dispatch("sms/openSmsDialog", {
        name: "",
        age: "",
        phone: "",
        deptName: "",
        wardName: "",
        smsTemplate: "",
      });
    },
    // å‘送短信
    async sendSms() {
      if (!this.smsContent.trim()) {
        this.$modal.msgError("请输入短信内容");
        return;
      }
      if (!this.smsForm.telcode) {
        this.$modal.msgError("患者电话不能为空");
        return;
      }
      this.smsLoading = true;
      try {
        const res = await sendMsg({
          phone: this.smsForm.telcode,
          content: this.smsContent,
        });
        if (res.code === 200) {
          this.$modal.msgSuccess("短信发送成功");
          // âœ… é€šè¿‡ Vuex å…³é—­å¯¹è¯æ¡†
          this.$store.dispatch("sms/closeSmsDialog");
          this.smsContent = "";
        } else {
          this.$modal.msgError(res.msg || "发送失败");
        }
      } catch (error) {
        console.error("发送短信失败:", error);
        this.$modal.msgError("发送失败,请稍后重试");
      } finally {
        this.smsLoading = false;
      }
    },
    async updateStats() {
      try {
        // è¿™é‡Œå¯ä»¥æ›¿æ¢ä¸ºå®žé™…çš„ API è°ƒç”¨
src/components/CallButton/index.vue
@@ -162,7 +162,10 @@
          // å¤„理各种状态
          if (status.type === "registered") {
            this.handleRegistered();
          } else if (status.type === "failed" || status.type === "disconnected") {
          } else if (
            status.type === "failed" ||
            status.type === "disconnected"
          ) {
            this.handleDisconnected();
          } else if (status.type === "connecting") {
            this.handleConnecting();
@@ -172,7 +175,8 @@
        // ç›‘听通话状态变化
        sipService.onCallStatusChange = (status) => {
          this.callStatus = status.type;
          this.isCalling = status.type === "calling" || status.type === "connected";
          this.isCalling =
            status.type === "calling" || status.type === "connected";
          this.updateLastActivityTime(); // é€šè¯çŠ¶æ€å˜åŒ–æ—¶æ›´æ–°æ´»åŠ¨æ—¶é—´
          this.$emit("call-status-change", status);
@@ -180,7 +184,6 @@
        // è®¾ç½®è¶…时处理
        this.setupRegistrationTimeout();
      } catch (error) {
        console.error("SIP服务初始化失败:", error);
        this.handleDisconnected();
@@ -272,7 +275,10 @@
      }
      this.reconnectCount++;
      const delay = Math.min(this.reconnectDelay * Math.pow(1.5, this.reconnectCount - 1), 30000);
      const delay = Math.min(
        this.reconnectDelay * Math.pow(1.5, this.reconnectCount - 1),
        30000
      );
      console.log(`计划在${delay}ms后重连,第${this.reconnectCount}次尝试`);
@@ -295,12 +301,11 @@
        this.cleanupSipConnection();
        // ç­‰å¾…一段时间
        await new Promise(resolve => setTimeout(resolve, 1000));
        await new Promise((resolve) => setTimeout(resolve, 1000));
        // é‡æ–°åˆå§‹åŒ–
        await this.CallgetList(); // é‡æ–°èŽ·å–åˆ†æœºå·
        this.initSipService();
      } catch (error) {
        console.error("重连失败:", error);
        this.isReconnecting = false;
@@ -338,7 +343,7 @@
    async startCall() {
      if (!this.phoneNumber) {
        this.$message.error("请输入电话号码");
        this.$message.warning("请输入电话号码");
        return;
      }
@@ -357,6 +362,15 @@
      } catch (error) {
        console.error("呼叫失败1:", error);
        if (
          error.message.includes("Canceled") ||
          error.message.includes("未注册")
        ) {
          console.warn("呼叫因页面离开或未注册而取消,不重试");
          this.callStatus = "ended";
          this.isCalling = false;
          return;
        }
        try {
          // å°è¯•加0再次呼叫
          const { canCall, reason } = sipService.canMakeCall();
@@ -371,7 +385,7 @@
        } catch (error) {
          this.callStatus = "ended";
          this.isCalling = false;
          this.$message.error("呼叫失败,请检查网络或号码");
          this.$message.warning("当前呼叫占线中,请稍后再拨");
        }
      }
    },
@@ -451,7 +465,11 @@
    },
  },
  beforeUnmount() {
    this.cleanupResources();
    if (this.isCalling) {
      this.endCall(); // å†…部设置了 isManualEnd
    }
    // å…¶ä»–清理(如定时器)...
    this.cleanupResources(); // ä½†æ³¨æ„ä¸è¦é‡å¤æ¸…理定时器,可优化判断
  },
};
</script>
src/components/StatisticsCards/index.vue
@@ -6,8 +6,8 @@
        :key="index"
        :xs="12"
        :sm="8"
        :md="colSpan"
        :lg="colSpan"
        :md="dynamicColSpan"
        :lg="dynamicColSpan"
      >
        <el-tooltip
          :content="getTooltipContent(item.name)"
@@ -20,15 +20,16 @@
            :body-style="item.router ? 'cursor: pointer' : 'cursor: default'"
            :class="getCardClass(item.name)"
          >
            <div
              class="card-content"
              @click="handleCardClick(item)"
            >
            <div class="card-content" @click="handleCardClick(item)">
              <div class="card-label">
                <span class="label-text">{{ item.name }}</span>
              </div>
              <div class="card-value">
                {{ item.value !== undefined && item.value !== null ? item.value : 0 }}
                {{
                  item.value !== undefined && item.value !== null
                    ? item.value
                    : 0
                }}
              </div>
            </div>
          </el-card>
@@ -44,28 +45,28 @@
  props: {
    cardlist: {
      type: Array,
      default: () => []
      default: () => [],
    },
    colSpan: {
      type: Number,
      default: 4
      default: 4,
    },
    showExtra: {
      type: Boolean,
      default: true
      default: true,
    },
    ycvalue: {
      type: Number,
      default: 0
      default: 0,
    },
    jgvalue: {
      type: Number,
      default: 0
      default: 0,
    },
    showWarningCondition: {
      type: Boolean,
      default: false
    }
      default: false,
    },
  },
  computed: {
    mergedCardList() {
@@ -74,43 +75,52 @@
      if (this.showExtra) {
        list.push({
          name: "异常",
          value: this.ycvalue
          value: this.ycvalue,
        });
      }
      if (this.showWarningCondition) {
        list.push({
          name: "警告",
          value: this.jgvalue
          value: this.jgvalue,
        });
      }
      return list;
    }
    },
    // åŠ¨æ€è®¡ç®—æ¯åˆ—å çš„æ …æ ¼æ•°
    dynamicColSpan() {
      const totalCards = this.mergedCardList.length;
      if (totalCards <= 4) return 6; // ä¸€è¡Œ4个
      if (totalCards <= 6) return 4; // ä¸€è¡Œ6个
      if (totalCards <= 8) return 3; // ä¸€è¡Œ8个
      return 2; // ä¸€è¡Œ12个
    },
  },
  methods: {
    getCardClass(name) {
      const classMap = {
        "患者服务总量": "total-card",
        "无需随访": "no-follow-card",
        "需随访": "need-follow-card",
        "待随访": "pending-card",
        "已完成": "completed-card",
        "异常": "error-card",
        "警告": "warning-card"
        æ‚£è€…服务总量: "total-card",
        æ— éœ€éšè®¿: "no-follow-card",
        éœ€éšè®¿: "need-follow-card",
        å¾…随访: "pending-card",
        å·²å®Œæˆ: "completed-card",
        å¼‚常: "error-card",
        è­¦å‘Š: "warning-card",
      };
      return classMap[name] || "default-card";
    },
    getTooltipContent(name) {
      const tooltips = {
        "患者服务总量": "患者服务总量 = æ— éœ€éšè®¿ + éœ€éšè®¿",
        "无需随访": "无需随访:不需要进行随访的患者数量",
        "需随访": "需随访 = å¾…随访 + å·²å®Œæˆ",
        "待随访": "待随访:等待进行随访的患者数量",
        "已完成": "已完成:已完成随访的患者数量",
        "异常": "异常数据统计",
        "警告": "警告数据统计"
        æ‚£è€…服务总量: "患者服务总量 = æ— éœ€éšè®¿ + éœ€éšè®¿",
        æ— éœ€éšè®¿: "无需随访:不需要进行随访的患者数量",
        éœ€éšè®¿: "需随访 = å¾…随访 + å·²å®Œæˆ",
        å¾…随访: "待随访:等待进行随访的患者数量",
        å·²å®Œæˆ: "已完成:已完成随访的患者数量",
        å¼‚常: "异常数据统计",
        è­¦å‘Š: "警告数据统计",
      };
      return tooltips[name] || "";
    },
@@ -120,8 +130,8 @@
        this.$router.push(item.router);
      }
      this.$emit("card-click", item);
    }
  }
    },
  },
};
</script>
src/store/index.js
@@ -7,6 +7,7 @@
import tagsView from './modules/tagsView'
import permission from './modules/permission'
import settings from './modules/settings'
import sms from './modules/sms'
import getters from './getters'
Vue.use(Vuex)
@@ -19,7 +20,8 @@
    regular,
    tagsView,
    permission,
    settings
    settings,
    sms
  },
  getters
})
src/store/modules/sms.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
// src/store/modules/sms.js
const state = {
  // çŸ­ä¿¡å¯¹è¯æ¡†æ˜¯å¦å¯è§
  smsDialogVisible: false,
  // æ‚£è€…数据
  patientData: {
    sendname: '',
    age: '',
    telcode: '',
    deptname: '',
    leavehospitaldistrictname: '',
  },
  // çŸ­ä¿¡æ¨¡æ¿
  smsTemplate: '',
};
const mutations = {
  // æ‰“开短信对话框
  OPEN_SMS_DIALOG(state, patientData) {
    console.log(11);
    state.smsDialogVisible = true;
    if (patientData) {
      state.patientData = {
        sendname: patientData.name || '',
        age: patientData.age || '',
        telcode: patientData.phone || '',
        deptname: patientData.deptName || '',
        leavehospitaldistrictname: patientData.wardName || '',
      };
      state.smsTemplate = patientData.smsTemplate || '';
    }
  },
  // å…³é—­çŸ­ä¿¡å¯¹è¯æ¡†
  CLOSE_SMS_DIALOG(state) {
    state.smsDialogVisible = false;
    state.smsTemplate = '';
  },
  // æ›´æ–°çŸ­ä¿¡å†…容
  UPDATE_SMS_CONTENT(state, content) {
    state.smsTemplate = content;
  },
};
const actions = {
  // æ‰“开短信对话框
  openSmsDialog({ commit }, patientData) {
    commit('OPEN_SMS_DIALOG', patientData);
  },
  // å…³é—­çŸ­ä¿¡å¯¹è¯æ¡†
  closeSmsDialog({ commit }) {
    commit('CLOSE_SMS_DIALOG');
  },
};
export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
src/store/modules/user.js
@@ -251,6 +251,12 @@
              localStorage.setItem("deptCode", "");
              localStorage.setItem("YongHuID", "");
              localStorage.setItem("YongHuXM", "");
            } else if (orgid == "47226007033110211A5201") {
              localStorage.setItem("orgname", "丽水市第二人民医院");
              localStorage.setItem("ZuHuID", "");
              localStorage.setItem("deptCode", "");
              localStorage.setItem("YongHuID", "");
              localStorage.setItem("YongHuXM", "");
            }
            resolve();
          })
src/utils/sipService.js
@@ -35,6 +35,7 @@
    this.isRegistered = false; // æ–°å¢žæ³¨å†ŒçŠ¶æ€æ ‡å¿—
    this.registrationTime = null; // æ–°å¢žæ³¨å†ŒæˆåŠŸæ—¶é—´æˆ³
    this.currentConfig = null; // å­˜å‚¨å½“前配置
    this.isManualEnd = false;
  }
  // èŽ·å–åŒ»é™¢é…ç½®æ–¹æ³•
  getHospitalConfig() {
@@ -136,7 +137,7 @@
  makeCall(targetNumber) {
    const { canCall, reason } = this.canMakeCall();
    if (!canCall) {
      Message.error(reason);
      Message.info(reason);
      return Promise.reject(new Error(reason));
    }
    return new Promise((resolve, reject) => {
@@ -162,6 +163,10 @@
          eventHandlers: {
            progress: () => this.updateCallStatus("calling", "呼叫中..."),
            failed: (e) => {
              if (this.isManualEnd) {
                console.log("主动挂断,忽略失败事件");
                return;
              }
              this.handleCallFailure(e, reject);
            },
            ended: () => this.updateCallStatus("ended", "通话结束"),
@@ -419,9 +424,12 @@
  endCall() {
    if (this.currentSession) {
    this.isManualEnd = true;
      this.currentSession.terminate();
      this.updateCallStatus("ended", "通话已结束");
    this.updateCallStatus('ended', '通话已结束');
      this.currentSession = null;
    // å»¶è¿Ÿé‡ç½®æ ‡å¿—,避免影响后续事件
    setTimeout(() => { this.isManualEnd = false; }, 100);
    }
  }
src/views/Satisfaction/sfstatistics/IndicatorStatistics.vue
@@ -25,7 +25,7 @@
import SatisfactionStatistics from "./components/SatisfactionStatistics.vue";
export default {
  name: "StatisticsMain",
  name: "Satisfaction",
  components: {
    FollowupStatistics,
    SatisfactionStatistics,
src/views/Satisfaction/sfstatistics/index.vue
@@ -19,25 +19,25 @@
</template>
<script>
import FollowupStatistics from './components/FollowupStatistics.vue';
import SatisfactionStatistics from './components/SatisfactionStatistics.vue';
import FollowupStatistics from "./components/FollowupStatistics.vue";
import SatisfactionStatistics from "./components/SatisfactionStatistics.vue";
export default {
  name: 'StatisticsMain',
  name: "Satisfaction",
  components: {
    FollowupStatistics,
    SatisfactionStatistics
    SatisfactionStatistics,
  },
  data() {
    return {
      activeTab: 'followup'
      activeTab: "followup",
    };
  },
  methods: {
    handleTabChange(tab) {
      console.log('切换到:', tab.name);
    }
  }
      console.log("切换到:", tab.name);
    },
  },
};
</script>
src/views/followvisit/discharge/index.vue
@@ -486,7 +486,6 @@
          prop="nurseName"
        />
        <el-table-column
          v-if="orgname != '丽水市中医院'"
          label="经管医生"
          align="center"
          key="managementDoctor"
@@ -1096,7 +1095,7 @@
      dynamicTags: ["选项一", "选项二", "选项三"], //选项
      inputVisible: false,
      Labelchange: false,
      ycvalue: "",
      ycvalue: 0,
      jgvalue: "",
      yfsvalue: "",
      inputValue: "",
@@ -1205,7 +1204,8 @@
        btstatus: "",
      },
      // endOut: 1,
      endOut: localStorage.getItem("orgname") == "丽水市中医院" ? 0 : 1, //0 å‡ºé™¢æ—¶é—´(正序)    1 å‡ºé™¢æ—¶é—´(倒序)   2 å‘送时间(正序)    3 å‘送时间(倒序)  7应随访日期(倒序) åº”随访日期(正序)
      endOut:
        localStorage.getItem("orgname") == "景宁畲族自治县人民医院" ? 0 : 1, //0 å‡ºé™¢æ—¶é—´(正序)    1 å‡ºé™¢æ—¶é—´(倒序)   2 å‘送时间(正序)    3 å‘送时间(倒序)  7应随访日期(倒序) åº”随访日期(正序)
      endOuts: [
        {
          value: 0,
@@ -1362,10 +1362,9 @@
    // ç›‘听路由参数变化
    "$route.query": {
      handler(newQuery, oldQuery) {
        if (newQuery.errtype !== oldQuery.errtype) {
        if (newQuery?.errtype !== oldQuery?.errtype) {
          console.log(22);
          this.loadData(); // é‡æ–°åŠ è½½æ•°æ®
          this.loadData();
        }
      },
      immediate: true,
@@ -1478,7 +1477,7 @@
            Number(response.rows[0].wxsf) + Number(response.rows[0].xsf) || 0;
          // this.cardlist[1].value = response.rows[0].wzx;
          this.cardlist[1].value = response.rows[0].wxsf || 0;
          this.ycvalue = response.rows[0].yc;
          this.ycvalue = Number(response.rows[0].yc) || 0
          this.jgvalue = response.rows[0].jg;
          this.cardlist[2].value = response.rows[0].xsf || 0;
          this.cardlist[3].value = response.rows[0].dsf || 0;
@@ -1589,7 +1588,7 @@
          Number(response.rows[0].wxsf) + Number(response.rows[0].xsf) || 0;
        this.cardlist[1].value = response.rows[0].wzx;
        this.cardlist[2].value = response.rows[0].ysf;
        this.ycvalue = response.rows[0].yc;
        this.ycvalue = Number(response.rows[0].yc) || 0
        this.jgvalue = response.rows[0].jg;
        this.cardlist[3].value = response.rows[0].fssb;
        this.cardlist[4].value = response.rows[0].dsf;
@@ -1761,6 +1760,8 @@
      this.handleQuery(1);
    },
    handleSelectionChange(rows) {
      console.log(rows, 911);
      this.selectedRows = rows.map((row) => {
        // åˆå§‹åŒ–评分字段
        return {
@@ -2080,6 +2081,7 @@
      const originalPageSize = this.topqueryParams.pageSize;
      this.topqueryParams.pageNum = null;
      this.topqueryParams.pageSize = null;
      this.topqueryParams.subIdList = this.selectedRows.map((item) => item.id);
      this.download(
        "smartor/serviceSubtask/patItemExport",
        {
src/views/followvisit/operation/index.vue
@@ -1,6 +1,12 @@
<template>
  <div class="app-container">
    <div class="leftvlue" style="margin-bottom: 20px">
    <statistics-cards
      :cardlist="cardlist"
      :ycvalue="ycvalue"
      :jgvalue="jgvalue"
      :show-warning-condition="orgname == '省立同德翠苑院区'"
    />
    <!-- <div class="leftvlue" style="margin-bottom: 20px">
      <el-row :gutter="10">
        <el-col :span="2.5" v-for="(item, index) in cardlist" :key="index">
          <el-card
@@ -80,7 +86,7 @@
          </div>
        </el-col>
      </el-row>
    </div>
    </div> -->
    <el-row :gutter="20">
      <!--用户数据-->
      <el-form
@@ -1133,13 +1139,15 @@
} from "@/api/AiCentre/index";
import { alterpatient, particularpatient } from "@/api/patient/homepage";
import Treeselect from "@riophae/vue-treeselect";
import StatisticsCards from "@/components/StatisticsCards";
import store from "@/store";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
  name: "Discharge",
  dicts: ["sys_normal_disable", "sys_user_sex", "sys_yujing", "sys_suggest"],
  components: { Treeselect },
  components: { Treeselect, StatisticsCards },
  data() {
    return {
      // é®ç½©å±‚
src/views/followvisit/record/TracingInfo/index.vue
@@ -1924,7 +1924,7 @@
          const targetDate = new Date(this.form.visitTime); // ç›®æ ‡æ—¥æœŸ
          const now = new Date(); // å½“前时间
          if (now < targetDate && this.form.sendstate == 2) {
            this.$confirm("当前服务未到发送时间请谨慎修改", "提示", {
            this.$confirm("当前服务未到随访时间请谨慎修改", "提示", {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "warning",
src/views/followvisit/record/detailpage/index copy.vue
@@ -2117,7 +2117,7 @@
          const targetDate = new Date(this.form.visitTime); // ç›®æ ‡æ—¥æœŸ
          const now = new Date(); // å½“前时间
          if (now < targetDate && this.form.sendstate == 2) {
            this.$confirm("当前服务未到发送时间请谨慎修改", "提示", {
            this.$confirm("当前服务未到随访时间请谨慎修改", "提示", {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "warning",
src/views/followvisit/record/detailpage/index.vue
@@ -107,6 +107,7 @@
                effect="dark"
                :content="scope.row.remark"
                placement="top-start"
                popper-class="statistics-tooltip"
              >
                <div v-if="scope.row.sendstateView == 1">
                  <el-tag type="primary" :disable-transitions="false"
@@ -114,22 +115,12 @@
                  >
                </div>
                <div v-if="scope.row.sendstateView == 2">
                  <el-tag type="primary" :disable-transitions="false"
                    >随访中</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstateView == 3">
                  <el-tag type="warning" :disable-transitions="false"
                    >未完成</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstateView == 4">
                  <el-tag type="success" :disable-transitions="false"
                    >已完成</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstateView == 5">
                  <el-tag type="danger" :disable-transitions="false"
                <div v-if="scope.row.sendstateView == 3">
                  <el-tag type="warning" :disable-transitions="false"
                    >无需随访</el-tag
                  >
                </div>
@@ -182,7 +173,58 @@
            key="drname"
            prop="drname"
          />
          <el-table-column
            label="任务状态"
            align="center"
            key="sendstate"
            prop="sendstate"
            width="120"
          >
            <template slot-scope="scope">
              <el-tooltip
                class="item"
                effect="dark"
                :content="scope.row.remark"
                placement="top-start"
              >
                <div v-if="scope.row.sendstate == 1">
                  <el-tag type="primary" :disable-transitions="false"
                    >表单已领取</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstate == 2">
                  <el-tag type="primary" :disable-transitions="false"
                    >待随访</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstate == 3">
                  <el-tag type="success" :disable-transitions="false"
                    >表单已发送</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstate == 4">
                  <el-tag type="info" :disable-transitions="false"
                    >不执行</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstate == 5">
                  <el-tag type="danger" :disable-transitions="false"
                    >发送失败</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstate == 6">
                  <el-tag type="success" :disable-transitions="false"
                    >已完成</el-tag
                  >
                </div>
                <div v-if="scope.row.sendstate == 7">
                  <el-tag type="danger" :disable-transitions="false"
                    >超时</el-tag
                  >
                </div>
              </el-tooltip>
            </template>
          </el-table-column>
          <el-table-column
            label="结果状态"
            align="center"
@@ -279,7 +321,12 @@
        <div class="call-container">
          <div
            style="display: flex"
            v-if="orgname == '南华大学附属第一医院' && !Voicetype"
            v-if="
              (orgname == '南华大学附属第一医院' ||
                orgname == '丽水市第二人民医院' ||
                orgname == '缙云县人民医院') &&
              !Voicetype
            "
          >
            <template-selector
              v-model="form.templateid"
@@ -998,34 +1045,21 @@
      <!-- æ³¨æ„è¿™é‡Œä½¿ç”¨äº† smsDialogVisible ä»¥åŒºåˆ†å·²æœ‰çš„ dialogFormVisible -->
      <el-form ref="smsForm" :model="form" label-width="80px">
        <el-form-item label="患者名称">
          <el-input
            style="width: 400px"
            disabled
            v-model="form.sendname"
          ></el-input>
          <el-input style="width: 400px" v-model="form.sendname"></el-input>
        </el-form-item>
        <el-form-item label="年龄">
          <el-input style="width: 400px" disabled v-model="form.age"></el-input>
          <el-input style="width: 400px" v-model="form.age"></el-input>
        </el-form-item>
        <el-form-item label="电话">
          <el-input
            style="width: 400px"
            disabled
            v-model="userform.telcode"
          ></el-input>
          <el-input style="width: 400px" v-model="userform.telcode"></el-input>
          <!-- æ³¨æ„è¿™é‡Œå¯èƒ½ä½¿ç”¨ userform.telcode -->
        </el-form-item>
        <el-form-item label="科室">
          <el-input
            style="width: 400px"
            disabled
            v-model="form.deptname"
          ></el-input>
          <el-input style="width: 400px" v-model="form.deptname"></el-input>
        </el-form-item>
        <el-form-item label="病区">
          <el-input
            style="width: 400px"
            disabled
            v-model="form.leavehospitaldistrictname"
          ></el-input>
        </el-form-item>
@@ -1670,7 +1704,6 @@
    },
    getconfigKey() {
      getconfigKey("default.value.icon").then((res) => {
        if (res.msg) {
          if (
            this.getAssignArr(res.msg).includes(this.$store.state.user.name) ||
@@ -2000,29 +2033,29 @@
            this.Torouter();
            return;
          }
          this.$modal
            .confirm(
              '任务保存成功是否针对患者:"' +
                this.userform.name +
                '"再次随访?',
              "确认",
              {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                showCancelButton: true,
                dangerouslyUseHTMLString: true,
                confirmButtonClass: "custom-confirm-button", // è‡ªå®šä¹‰ç¡®è®¤æŒ‰é’®çš„类名
                cancelButtonClass: "custom-cancel-button", // è‡ªå®šä¹‰å–消按钮的类名
              }
            )
            .then(() => {
              document.querySelector("#app").scrollTo(0, 0);
              this.formtidy();
              this.dialogFormVisible = true;
            })
            .catch(() => {
              this.Torouter();
            });
          // this.$modal
          //   .confirm(
          //     '任务保存成功是否针对患者:"' +
          //       this.userform.name +
          //       '"再次随访?',
          //     "确认",
          //     {
          //       confirmButtonText: "确定",
          //       cancelButtonText: "取消",
          //       showCancelButton: true,
          //       dangerouslyUseHTMLString: true,
          //       confirmButtonClass: "custom-confirm-button", // è‡ªå®šä¹‰ç¡®è®¤æŒ‰é’®çš„类名
          //       cancelButtonClass: "custom-cancel-button", // è‡ªå®šä¹‰å–消按钮的类名
          //     }
          //   )
          //   .then(() => {
          //     document.querySelector("#app").scrollTo(0, 0);
          //     this.formtidy();
          //     this.dialogFormVisible = true;
          //   })
          //   .catch(() => {
          //     this.Torouter();
          //   });
        }
      });
    },
@@ -2266,29 +2299,31 @@
      savequestiondetail(obj).then((res) => {
        if (res.code == 200) {
          this.$modal.msgSuccess("服务保存成功");
          this.$modal
            .confirm(
              '任务保存成功是否针对患者:"' +
                this.userform.name +
                '"再次随访?',
              "确认",
              {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                showCancelButton: true,
                dangerouslyUseHTMLString: true,
                confirmButtonClass: "custom-confirm-button", // è‡ªå®šä¹‰ç¡®è®¤æŒ‰é’®çš„类名
                cancelButtonClass: "custom-cancel-button", // è‡ªå®šä¹‰å–消按钮的类名
              }
            )
            .then(() => {
              document.querySelector("#app").scrollTo(0, 0);
              this.formtidy();
              this.dialogFormVisible = true;
            })
            .catch(() => {
              this.Torouter();
            });
          //   this.$modal
          //     .confirm(
          //       '任务保存成功是否针对患者:"' +
          //         this.userform.name +
          //         '"再次随访?',
          //       "确认",
          //       {
          //         confirmButtonText: "确定",
          //         cancelButtonText: "取消",
          //         showCancelButton: true,
          //         dangerouslyUseHTMLString: true,
          //         confirmButtonClass: "custom-confirm-button", // è‡ªå®šä¹‰ç¡®è®¤æŒ‰é’®çš„类名
          //         cancelButtonClass: "custom-cancel-button", // è‡ªå®šä¹‰å–消按钮的类名
          //       }
          //     )
          //     .then(() => {
          //       document.querySelector("#app").scrollTo(0, 0);
          //       this.formtidy();
          //       this.dialogFormVisible = true;
          //     })
          //     .catch(() => {
          //       this.Torouter();
          //     });
        }
      });
    },
@@ -2336,7 +2371,7 @@
          console.log(targetDate, "目标日期");
          if (now < targetDate && this.form.sendstate == 2) {
            this.$confirm("当前服务未到发送时间请谨慎修改", "提示", {
            this.$confirm("当前服务未到随访时间请谨慎修改", "提示", {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "warning",
@@ -2391,6 +2426,7 @@
          objson = res.rows[0].serviceSubtaskList[0];
          objson.suggest = son;
          objson.remark = this.form.remark;
          objson.sendstate = this.serviceStates;
          objson.taskSituation = this.form.taskSituation;
          Editsingletaskson(objson).then((res) => {
            if (res.code) {
@@ -2432,13 +2468,14 @@
      });
    },
    alterpatient(sendstate) {
      alterpatient(this.userform).then((res) => {
        if (res.code == 200) {
          this.$modal.msgSuccess("基础信息保存成功");
        } else {
          this.$modal.msgError("基础信息修改失败");
        }
      });
      this.Editsingletasksonyic(this.serviceStates)
      // alterpatient(this.userform).then((res) => {
      //   if (res.code == 200) {
      //     this.$modal.msgSuccess("基础信息保存成功");
      //   } else {
      //     this.$modal.msgError("基础信息修改失败");
      //   }
      // });
    },
    // å¼‚常列渲染
    tableRowClassName({ row, rowIndex }) {
@@ -2830,14 +2867,38 @@
  //   console.log(11);
  // },
  beforeRouteLeave(to, from, next) {
    this.$refs.callButton.cleanupResources();
    if (this.$refs.CallCenterLs) {
      console.log(1);
  const callButton = this.$refs.callButton;
  // å¦‚果存在呼叫组件且正在通话中
  if (callButton && callButton.isCalling) {
    this.$confirm('当前正在通话中,确定要离开此页面吗?', '提示', {
      confirmButtonText: '挂断并离开',
      cancelButtonText: '继续通话',
      type: 'warning'
    })
      .then(() => {
        // ç”¨æˆ·ç¡®è®¤ç¦»å¼€ï¼Œä¸»åŠ¨æŒ‚æ–­å¹¶æ¸…ç†
        callButton.cleanupResources();
        if (this.$refs.CallCenterLs) {
      this.$refs.CallCenterLs.handleSeatLogout();
    }
    next(); // ç¡®ä¿è°ƒç”¨ nex
  },
        next();
      })
      .catch(() => {
        // ç”¨æˆ·å–消,阻止路由跳转
        next(false);
      });
  } else {
    // æœªé€šè¯æˆ–呼叫组件不存在,正常清理
    if (callButton) {
      callButton.cleanupResources();
    }
    if (this.$refs.CallCenterLs) {
      this.$refs.CallCenterLs.handleSeatLogout();
    }
    next();
  }
}
  // beforeRouteUpdate() {
  //   console.log(33);
  // },
src/views/followvisit/record/physical/index.vue
@@ -1040,7 +1040,7 @@
          const now = new Date(); // å½“前时间
          this.form.endtime = this.formatTime(this.form.endtime);
          if (now < targetDate && this.form.sendstate == 2) {
            this.$confirm("当前服务未到发送时间请谨慎修改", "提示", {
            this.$confirm("当前服务未到随访时间请谨慎修改", "提示", {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "warning",
src/views/followvisit/tasklist/index.vue
@@ -1003,7 +1003,9 @@
    // æš‚停
    stop(row) {
      console.log(row);
      this.$modal
        .confirm('是否确认暂停"' + row.taskName + '"?')
        .then(function () {
      if (row.sendState == 2) {
        this.TaskOperation.taskId = row.taskid;
        this.TaskOperation.sendState = 3;
@@ -1014,6 +1016,9 @@
          this.getList();
        });
      }
        })
        .catch(() => {});
    },
    /** æäº¤æŒ‰é’® */
src/views/knowledge/questionnaire/index.vue
@@ -478,7 +478,7 @@
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
  name: "questionnaire",
  name: "Questionnaire",
  components: { Treeselect },
  data() {
    return {
src/views/knowledge/questionnaire/smsConfig/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1037 @@
<template>
  <div class="smsConfig-management">
    <!-- å·¦ä¾§æ  -->
    <div class="sidecolumn">
      <div class="sidecolumn-top">
        <div class="top-wj">模板分类</div>
        <div class="top-tj" @click="Newcategory">+添加</div>
      </div>
      <div class="center-ss">
        <el-input
          placeholder="请输入内容"
          v-model="sidecolumnval"
          class="input-with-select"
          size="medium"
        >
        </el-input>
      </div>
      <div class="head-container" style="margin-top: 20px">
        <el-tree
          :data="deptOptions"
          :props="defaultProps"
          :expand-on-click-node="false"
          :filter-node-method="filterNode"
          ref="tree"
          node-key="id"
          default-expand-all
          highlight-current
          @node-click="handleNodeClick"
        >
          <span class="custom-tree-node" slot-scope="{ node, data }">
            <span class="tree-node-label">{{ node.label }}</span>
            <span v-if="data.id > 0">
              <el-button
                type="text"
                icon="el-icon-delete"
                circle
                size="mini"
                @click="() => remove(node, data)"
              >
              </el-button>
            </span>
            <span v-if="data.id > 0">
              <el-button
                type="text"
                circle
                size="mini"
                @click="() => altertag(node, data)"
              >
                <span class="button-textxg">
                  <i class="el-icon-edit-outline"></i>
                </span>
              </el-button>
            </span>
          </span>
        </el-tree>
      </div>
    </div>
    <!-- å³ä¾§æ•°æ® -->
    <div class="leftvlue">
      <div class="leftvlue-bg">
        <el-row :gutter="20">
          <el-col :span="24" :xs="24">
            <el-form
              :model="queryParams"
              ref="queryForm"
              size="small"
              :inline="true"
              v-show="showSearch"
              label-width="98px"
            >
              <el-form-item label="模板名称" prop="templetname">
                <el-input
                  v-model="queryParams.templetname"
                  placeholder="请输入模板名称"
                  clearable
                  style="width: 200px"
                  @keyup.enter.native="handleQuery"
                />
              </el-form-item>
              <el-form-item label="短信签名" prop="signature">
                <el-input
                  v-model="queryParams.signature"
                  placeholder="请输入短信签名"
                  clearable
                  style="width: 200px"
                  @keyup.enter.native="handleQuery"
                />
              </el-form-item>
              <el-form-item label="启用状态" prop="isenable">
                <el-select
                  v-model="queryParams.isenable"
                  placeholder="请选择状态"
                  clearable
                  style="width: 200px"
                >
                  <el-option
                    v-for="item in statusOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  icon="el-icon-search"
                  size="medium"
                  @click="handleQuery"
                >搜索</el-button>
                <el-button
                  icon="el-icon-refresh"
                  size="medium"
                  @click="resetQuery"
                >重置</el-button>
              </el-form-item>
            </el-form>
            <el-divider></el-divider>
            <el-row :gutter="10" class="mb8">
              <el-col :span="1.5">
                <el-button
                  type="primary"
                  plain
                  icon="el-icon-plus"
                  size="medium"
                  @click="handleAdd"
                >新增</el-button>
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="danger"
                  plain
                  icon="el-icon-delete"
                  size="medium"
                  :disabled="multiple"
                  @click="handleDelete"
                >删除</el-button>
              </el-col>
            </el-row>
            <el-table
              v-loading="loading"
              :data="userList"
              :border="true"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="50" align="center" />
              <el-table-column
                label="模板名称"
                align="center"
                key="templetname"
                prop="templetname"
                width="160"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="短信签名"
                align="center"
                key="signature"
                prop="signature"
                width="120"
              />
              <el-table-column
                label="模板内容"
                align="center"
                key="templetcontent"
                prop="templetcontent"
                width="280"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="模板类型"
                align="center"
                key="templettype"
                prop="templettype"
                width="120"
              >
                <template slot-scope="scope">
                  <dict-tag :options="typeOptions" :value="scope.row.templettype" />
                </template>
              </el-table-column>
              <el-table-column
                label="启用状态"
                align="center"
                key="isenable"
                prop="isenable"
                width="100"
              >
                <template slot-scope="scope">
                  <dict-tag :options="statusOptions" :value="scope.row.isenable" />
                </template>
              </el-table-column>
              <el-table-column
                label="备注"
                align="center"
                key="remark"
                prop="remark"
                width="180"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="创建时间"
                align="center"
                key="createTime"
                prop="createTime"
                width="160"
              />
              <el-table-column
                label="操作"
                fixed="right"
                align="center"
                width="240"
                class-name="small-padding fixed-width"
              >
                <template slot-scope="scope">
                  <el-button
                    size="medium"
                    type="text"
                    @click="handleUpdate(scope.row)"
                  >
                    <span class="button-textxg">
                      <i class="el-icon-edit"></i>修改
                    </span>
                  </el-button>
                  <el-button
                    size="medium"
                    type="text"
                    @click="handlePreview(scope.row)"
                  >
                    <span class="button-text">
                      <i class="el-icon-view"></i>预览
                    </span>
                  </el-button>
                  <el-button
                    size="medium"
                    type="text"
                    @click="handleDelete(scope.row)"
                  >
                    <span class="button-textsc">
                      <i class="el-icon-edit"></i>删除
                    </span>
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
            <pagination
              v-show="total > 0"
              :total="total"
              :page.sync="queryParams.pageNum"
              :limit.sync="queryParams.pageSize"
              @pagination="getList"
            />
          </el-col>
        </el-row>
      </div>
    </div>
    <!-- æ·»åŠ /修改短信模板弹框 -->
    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      width="45%"
      :close-on-click-modal="false"
    >
      <el-form
        :model="form"
        :rules="rules"
        ref="formRef"
        label-width="100px"
        size="medium"
      >
        <el-form-item label="模板分类" prop="categoryid">
          <el-select
            v-model="form.categoryid"
            placeholder="请选择模板分类"
            clearable
            style="width: 100%"
          >
            <el-option
              v-for="item in categoryOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="模板名称" prop="templetname">
          <el-input
            v-model="form.templetname"
            placeholder="请输入模板名称"
            maxlength="50"
          />
        </el-form-item>
        <el-form-item label="短信签名" prop="signature">
          <el-input
            v-model="form.signature"
            placeholder="请输入短信签名(如:【丽水人民医院】)"
            maxlength="20"
          />
        </el-form-item>
        <el-form-item label="模板内容" prop="templetcontent">
          <el-input
            v-model="form.templetcontent"
            type="textarea"
            :rows="5"
            placeholder="请输入短信模板内容"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="模板类型" prop="templettype">
          <el-select
            v-model="form.templettype"
            placeholder="请选择模板类型"
            style="width: 100%"
          >
            <el-option
              v-for="item in typeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="启用状态" prop="isenable">
          <el-radio-group v-model="form.isenable">
            <el-radio
              v-for="item in statusOptions"
              :key="item.value"
              :label="item.value"
            >{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="form.remark"
            type="textarea"
            :rows="3"
            placeholder="请输入备注信息"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelForm">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitForm" :loading="submitLoading">ç¡® å®š</el-button>
      </div>
    </el-dialog>
    <!-- æ¨¡æ¿é¢„览弹框 -->
    <el-dialog
      title="短信模板预览"
      :visible.sync="previewVisible"
      width="40%"
    >
      <div class="preview-box">
        <div class="preview-item">
          <div class="preview-label">模板名称:</div>
          <div class="preview-value">{{ previewData.templetname }}</div>
        </div>
        <div class="preview-item">
          <div class="preview-label">短信签名:</div>
          <div class="preview-value">{{ previewData.signature }}</div>
        </div>
        <div class="preview-item">
          <div class="preview-label">模板类型:</div>
          <div class="preview-value">
            <dict-tag :options="typeOptions" :value="previewData.templettype" />
          </div>
        </div>
        <div class="preview-item">
          <div class="preview-label">启用状态:</div>
          <div class="preview-value">
            <dict-tag :options="statusOptions" :value="previewData.isenable" />
          </div>
        </div>
        <el-divider></el-divider>
        <div class="preview-content">
          <div class="preview-content-label">短信内容预览:</div>
          <div class="preview-content-box">
            {{ previewData.templetcontent || '暂无内容' }}
          </div>
        </div>
        <div class="preview-item" v-if="previewData.remark">
          <div class="preview-label">备注:</div>
          <div class="preview-value">{{ previewData.remark }}</div>
        </div>
      </div>
    </el-dialog>
    <!-- æ·»åŠ ç±»åˆ«å¼¹æ¡† -->
    <el-dialog title="类别编辑" width="30%" :visible.sync="dialogFormVisible">
      <div style="text-align: center; margin-bottom: 20px">
        <el-radio-group v-model="radio">
          <el-radio-button label="主分类"></el-radio-button>
          <el-radio-button label="子分类"></el-radio-button>
        </el-radio-group>
      </div>
      <el-divider></el-divider>
      <el-form :model="classifyform">
        <el-form-item label="请选择模板大类" v-if="radio == '子分类'">
          <el-select v-model="classifyform.pid" placeholder="请选择">
            <el-option
              v-for="item in deptOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="请输入类别名称">
          <el-input v-model="classifyform.name" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="getDeptTree()">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitsidecolumn">ç¡® å®š</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import store from "@/store";
import {
  listSmstemplet,
  getSmstemplet,
  addSmstemplet,
  updateSmstemplet,
  delSmstemplet,
} from "@/api/smartor/smstemplet";
export default {
  name: "SmsConfig",
  data() {
    return {
      // é®ç½©å±‚
      loading: false,
      // æäº¤æŒ‰é’®loading
      submitLoading: false,
      // é€‰ä¸­æ•°ç»„
      ids: [],
      // éžå•个禁用
      single: true,
      // éžå¤šä¸ªç¦ç”¨
      multiple: true,
      // æ˜¾ç¤ºæœç´¢æ¡ä»¶
      showSearch: true,
      // æ€»æ¡æ•°
      total: 0,
      // è¡¨æ ¼æ•°æ®
      userList: [],
      // å¼¹æ¡†æ ‡é¢˜
      dialogTitle: "",
      // å¼¹æ¡†å¯è§æ€§
      dialogVisible: false,
      // é¢„览弹框
      previewVisible: false,
      // é¢„览数据
      previewData: {},
      // ç±»åˆ«å¼¹æ¡†
      dialogFormVisible: false,
      // ç±»åˆ«form
      classifyform: {},
      // ä¸»/子分类
      radio: "主分类",
      // ç±»åˆ«æœç´¢
      sidecolumnval: "",
      // æ ‘数据
      deptOptions: [],
      // åˆ†ç±»ä¸‹æ‹‰é€‰é¡¹
      categoryOptions: [],
      // æ ‘props
      defaultProps: {
        children: "children",
        label: "name",
      },
      // çŠ¶æ€é€‰é¡¹
      statusOptions: [
        { label: "启用", value: "0" },
        { label: "停用", value: "1" },
      ],
      // ç±»åž‹é€‰é¡¹
      typeOptions: [
        { label: "验证码", value: "0" },
        { label: "通知", value: "1" },
        { label: "营销", value: "2" },
        { label: "随访", value: "3" },
      ],
      // æŸ¥è¯¢å‚æ•°
      queryParams: {
        pageNum: 1,
        pageSize: 10,
      },
      // è¡¨å•
      form: {},
      // è¡¨å•校验
      rules: {
        templetname: [
          { required: true, message: "请输入模板名称", trigger: "blur" },
        ],
        templetcontent: [
          { required: true, message: "请输入模板内容", trigger: "blur" },
        ],
        signature: [
          { required: true, message: "请输入短信签名", trigger: "blur" },
        ],
        isenable: [
          { required: true, message: "请选择启用状态", trigger: "change" },
        ],
      },
    };
  },
  watch: {
    // ç›‘听类别搜索
    sidecolumnval(val) {
      this.$refs.tree.filter(val);
    },
  },
  created() {
    this.getList();
    this.getDeptTree();
  },
  methods: {
    /** æŸ¥è¯¢åˆ—表 */
    getList() {
      this.loading = true;
      listSmstemplet(this.queryParams).then((response) => {
        this.userList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    /** æœç´¢æŒ‰é’®æ“ä½œ */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** é‡ç½®æŒ‰é’®æ“ä½œ */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.templetid);
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    /** æ–°å¢žæŒ‰é’®æ“ä½œ */
    handleAdd() {
      this.dialogTitle = "新增短信模板";
      this.dialogVisible = true;
      this.form = {
        isenable: "0",
        templettype: "1",
      };
      // å¦‚果有树选中分类,默认带入
      if (this.queryParams.categoryid) {
        this.form.categoryid = this.queryParams.categoryid;
      }
      this.$nextTick(() => {
        if (this.$refs.formRef) {
          this.$refs.formRef.clearValidate();
        }
      });
    },
    /** ä¿®æ”¹æŒ‰é’®æ“ä½œ */
    handleUpdate(row) {
      this.dialogTitle = "修改短信模板";
      this.dialogVisible = true;
      const templetid = row.templetid || this.ids[0];
      getSmstemplet(templetid).then((response) => {
        this.form = response.data;
        this.$nextTick(() => {
          if (this.$refs.formRef) {
            this.$refs.formRef.clearValidate();
          }
        });
      });
    },
    /** é¢„览按钮操作 */
    handlePreview(row) {
      this.previewVisible = true;
      const templetid = row.templetid;
      getSmstemplet(templetid).then((response) => {
        this.previewData = response.data;
      });
    },
    /** æäº¤è¡¨å• */
    submitForm() {
      this.$refs.formRef.validate((valid) => {
        if (valid) {
          this.submitLoading = true;
          if (this.form.templetid) {
            // ä¿®æ”¹
            updateSmstemplet(this.form)
              .then(() => {
                this.$modal.msgSuccess("修改成功");
                this.dialogVisible = false;
                this.getList();
              })
              .finally(() => {
                this.submitLoading = false;
              });
          } else {
            // æ–°å¢ž
            addSmstemplet(this.form)
              .then(() => {
                this.$modal.msgSuccess("新增成功");
                this.dialogVisible = false;
                this.getList();
              })
              .finally(() => {
                this.submitLoading = false;
              });
          }
        }
      });
    },
    /** å–消表单 */
    cancelForm() {
      this.dialogVisible = false;
      this.form = {};
      this.$nextTick(() => {
        if (this.$refs.formRef) {
          this.$refs.formRef.clearValidate();
        }
      });
    },
    /** åˆ é™¤æŒ‰é’®æ“ä½œ */
    handleDelete(row) {
      const templetids = row.templetid || this.ids.join(",");
      this.$modal
        .confirm('是否确认删除模板编号为"' + templetids + '"的数据项?')
        .then(function () {
          return delSmstemplet(templetids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    // è¡¨å•重置
    reset() {
      this.form = {
        templetid: undefined,
        templetname: undefined,
        signature: undefined,
        templetcontent: undefined,
        templettype: "1",
        isenable: "0",
        categoryid: undefined,
        remark: undefined,
      };
      this.resetForm("form");
    },
    /** æŸ¥è¯¢åˆ†ç±»æ ‘ */
    getDeptTree() {
      // æ¨¡æ‹Ÿåˆ†ç±»æ ‘数据 - å®žé™…项目中应替换为真实API
      this.deptOptions = [
        {
          id: 1,
          name: "随访短信",
          children: [
            { id: 11, name: "出院随访" },
            { id: 12, name: "复诊提醒" },
            { id: 13, name: "健康宣教" },
          ],
        },
        {
          id: 2,
          name: "通知短信",
          children: [
            { id: 21, name: "预约通知" },
            { id: 22, name: "报告通知" },
          ],
        },
        {
          id: 3,
          name: "验证码",
          children: [
            { id: 31, name: "登录验证" },
            { id: 32, name: "注册验证" },
          ],
        },
      ];
      this.categoryOptions = this.flattenTree(this.deptOptions);
    },
    /** æ‰å¹³åŒ–树数据用于下拉选择 */
    flattenTree(tree) {
      let result = [];
      tree.forEach((item) => {
        result.push({ id: item.id, name: item.name });
        if (item.children && item.children.length) {
          result = result.concat(item.children);
        }
      });
      return result;
    },
    /** ç­›é€‰èŠ‚ç‚¹ */
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },
    /** ç‚¹å‡»æ ‘节点 */
    handleNodeClick(data) {
      if (data.children && data.children.length) return;
      this.queryParams.categoryid = data.id;
      this.getList();
    },
    // åˆ†ç±»æ ‘-----------------------
    /** æ–°å»ºåˆ†ç±» */
    Newcategory() {
      this.classifyform = {};
      this.radio = "主分类";
      this.dialogFormVisible = true;
    },
    /** ä¿®æ”¹åˆ†ç±» */
    altertag(node, data) {
      this.dialogFormVisible = true;
      if (data.children && data.children.length) {
        this.radio = "主分类";
      } else {
        this.radio = "子分类";
      }
      this.classifyform = { ...data };
    },
    /** æäº¤åˆ†ç±» */
    submitsidecolumn() {
      if (this.classifyform.id) {
        // ä¿®æ”¹åˆ†ç±» - å®žé™…项目中应替换为真实API
        const index = this.deptOptions.findIndex(
          (obj) => obj.id === this.classifyform.id
        );
        if (index > -1) {
          this.deptOptions[index].name = this.classifyform.name;
          this.$set(this.deptOptions, index, this.deptOptions[index]);
        }
        this.$modal.msgSuccess("修改成功");
        this.dialogFormVisible = false;
        return;
      }
      if (this.radio === "主分类" && this.classifyform.name) {
        // æ–°å¢žä¸»åˆ†ç±»
        const newId = Math.max(...this.deptOptions.map((d) => d.id), 0) + 1;
        this.deptOptions.push({
          id: newId,
          name: this.classifyform.name,
          children: [],
        });
        this.$modal.msgSuccess("新增成功");
        this.dialogFormVisible = false;
      } else if (
        this.radio === "子分类" &&
        this.classifyform.pid &&
        this.classifyform.name
      ) {
        // æ–°å¢žå­åˆ†ç±»
        const parent = this.deptOptions.find(
          (obj) => obj.id === this.classifyform.pid
        );
        if (parent) {
          const newChildId =
            Math.max(...parent.children.map((c) => c.id), parent.id * 10) + 1;
          parent.children.push({
            id: newChildId,
            name: this.classifyform.name,
          });
        }
        this.$modal.msgSuccess("新增成功");
        this.dialogFormVisible = false;
      } else {
        this.$modal.msgError("请填写完整信息");
      }
      this.classifyform = {};
    },
    /** åˆ é™¤åˆ†ç±» */
    remove(node, data) {
      if (data.children && data.children.length) {
        this.$modal
          .confirm(
            '是否确认删除一级分类"' + data.name + '"?删除后其下分类将无法使用'
          )
          .then(() => {
            const index = this.deptOptions.findIndex(
              (obj) => obj.id === data.id
            );
            if (index > -1) {
              this.deptOptions.splice(index, 1);
            }
            this.$modal.msgSuccess("删除成功");
          })
          .catch(() => {});
      } else {
        this.$modal
          .confirm('是否确认删除分类项为"' + data.name + '"的数据项?')
          .then(() => {
            this.deptOptions.forEach((parent) => {
              const idx = parent.children.findIndex(
                (child) => child.id === data.id
              );
              if (idx > -1) {
                parent.children.splice(idx, 1);
              }
            });
            this.$modal.msgSuccess("删除成功");
          })
          .catch(() => {});
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.smsConfig-management {
  display: flex;
}
.sidecolumn {
  width: 380px;
  min-height: 100vh;
  text-align: center;
  margin-top: 20px;
  margin: 20px;
  padding: 30px;
  background: #fff;
  border: 1px solid #dcdfe6;
  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
    0 0 6px 0 rgba(0, 0, 0, 0.04);
  .sidecolumn-top {
    display: flex;
    justify-content: space-between;
    .top-wj {
      font-size: 20px;
    }
    .top-tj {
      font-size: 18px;
      color: rgb(0, 89, 255);
      cursor: pointer;
    }
  }
  /* æ ¸å¿ƒï¼šè®¾ç½®å›ºå®šå®½åº¦ï¼Œè¶…出部分显示省略号 */
  .tree-node-label {
    display: inline-block;
    max-width: 160px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    vertical-align: bottom;
  }
  /* å¯é€‰ï¼šé¼ æ ‡æ‚¬åœæ—¶å–消限制,显示全文 */
  .custom-tree-node:hover .tree-node-label {
    max-width: none;
    white-space: normal;
    overflow: visible;
  }
  .center-ss {
    margin-top: 30px;
    .input-with-select {
      height: 40px !important;
    }
  }
  .bottom-fl {
    margin-top: 30px;
    display: center !important;
  }
}
.leftvlue {
  width: 80%;
  margin-top: 20px;
  padding: 30px;
  background: #ffff;
  border: 1px solid #dcdfe6;
  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
    0 0 6px 0 rgba(0, 0, 0, 0.04);
  .mulsz {
    font-size: 20px;
  }
}
// é¢„览弹框样式
.preview-box {
  padding: 10px 20px;
  .preview-item {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
    font-size: 15px;
    .preview-label {
      width: 100px;
      text-align: right;
      color: #606266;
      font-weight: 500;
    }
    .preview-value {
      flex: 1;
      margin-left: 10px;
      color: #303133;
    }
  }
  .preview-content {
    margin-bottom: 15px;
    .preview-content-label {
      color: #606266;
      font-weight: 500;
      margin-bottom: 10px;
      font-size: 15px;
    }
    .preview-content-box {
      padding: 15px;
      background: #f5f7fa;
      border: 1px solid #dcdfe6;
      border-radius: 4px;
      min-height: 60px;
      line-height: 1.8;
      color: #303133;
      word-break: break-all;
    }
  }
}
// æ·±åº¦é€‰æ‹©å™¨
::v-deep .el-input--medium .el-input__inner {
  height: 40px !important;
}
::v-deep .el-tree-node__content {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  height: 46px;
  font-size: 20px;
  cursor: pointer;
}
::v-deep .el-tree {
  position: relative;
  cursor: default;
  border-radius: 5px;
  background: #eff8fe;
  color: #606266;
  border: 1px solid #bbe1fa;
  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
    0 0 6px 0 rgba(0, 0, 0, 0.04);
}
::v-deep
  .el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  background-color: #7799fb;
  color: #fff;
}
::v-deep .el-button--mini.is-circle {
  padding: 7px;
  margin: 0;
  color: red;
}
// æŒ‰é’®æ–‡å­—颜色
.button-text {
  color: rgb(70, 204, 238);
}
.button-textxg {
  color: rgb(35, 81, 233);
}
.button-textsc {
  color: rgb(235, 23, 23);
}
</style>
src/views/outsideChainwtnew.vue
@@ -23,7 +23,9 @@
                  : "亲爱的患者-家属,我们是医院的医护人员,为了更好地了解您的康复情况,请您抽一点宝贵时间,完成这份随访问卷。"
              }}
            </div>
            <div v-if="orgname" class="questionnaire-signature">———{{ orgname }}</div>
            <div v-if="orgname" class="questionnaire-signature">
              â€”——{{ orgname }}
            </div>
          </div>
          <el-divider class="custom-divider"></el-divider>
@@ -327,6 +329,7 @@
        <div class="completion-content">
          <div class="completion-icon">✓</div>
          <h2 class="completion-title">感谢您的配合!</h2>
          <h2 class="completion-title">祝您健康快乐!</h2>
          <p class="completion-message">
            {{
              jsy
@@ -506,7 +509,15 @@
            res.data.param3,
            res.data.param5
          );
          if (
            res.data.orgname == "省立同德翠苑院区" ||
            res.data.orgname == "省立同德之江院区" ||
            res.data.orgname == "省立同德闲林院区"
          ) {
            this.orgname = "浙江省立同德医院";
          } else {
          this.orgname = res.data.orgname;
          }
          this.param6 = res.data.param6;
        }
@@ -895,7 +906,7 @@
.questionnaire-description {
  font-size: 16px;
  color: #5a6c84;
  color: #303a47;
  line-height: 1.8;
  max-width: 720px;
  margin: 0;
@@ -904,8 +915,8 @@
  text-indent: 2em; /* é¦–行缩进 */
}
.questionnaire-signature {
  font-size: 15px;
  color: #8a9bb5; /* æ¯”正文颜色稍浅,体现附属感 */
  font-size: 16px;
  color: #303a47;
  text-align: right; /* å³å¯¹é½ */
  max-width: 720px;
  margin: 8px 0 0 auto; /* ä¸Šè¾¹è·8px,右边靠齐 */
@@ -972,11 +983,21 @@
.question-stem {
  display: grid;
  grid-template-columns: auto 1fr auto; /* é¢˜å·è‡ªé€‚应,文本占满剩余空间,题型标签自适应 */
  grid-template-columns: auto 1fr auto;
  gap: 3px;
  align-items: center;
  align-items: start; /* æ”¹ä¸º start é¿å…å±…中导致的视觉问题 */
  margin-bottom: 20px;
  font-size: 18px;
}
.question-text {
  line-height: 1.5;
  color: #2c3e50;
  font-weight: 500;
  word-wrap: break-word;
  overflow-wrap: break-word;
  white-space: normal; /* ç¡®ä¿å…è®¸æ¢è¡Œ */
  min-width: 0; /* é˜²æ­¢ grid é¡¹æº¢å‡º */
}
.question-number {
@@ -985,14 +1006,14 @@
  min-width: 16px;
}
.question-text {
  line-height: 1.5;
  color: #2c3e50;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
// .question-text {
//   line-height: 1.5;
//   color: #2c3e50;
//   font-weight: 500;
//   overflow: hidden;
//   text-overflow: ellipsis;
//   white-space: nowrap;
// }
.question-type-tag {
  color: #3ba2f7;
@@ -1162,11 +1183,11 @@
    font-size: 16px;
  }
  .question-stem {
    font-size: 16px;
    flex-direction: column;
    align-items: flex-start;
  }
  // .question-stem {
  //   font-size: 16px;
  //   flex-direction: column;
  //   align-items: flex-start;
  // }
  .question-type-tag {
    margin-left: 0;
src/views/patient/patient/index.vue
@@ -182,7 +182,7 @@
                  >删除</el-button
                >
              </el-col>
              <el-col :span="1.5">
              <!-- <el-col :span="1.5">
                <el-button
                  type="primary"
                  icon="el-icon-s-promotion"
@@ -190,7 +190,7 @@
                  @click="distribute"
                  >向任务派发患者</el-button
                >
              </el-col>
              </el-col> -->
              <el-col :span="6">
                <div class="documentf">
                  <div class="document">
@@ -376,14 +376,14 @@
                      ><i class="el-icon-edit"></i>患者过滤</span
                    ></el-button
                  >
                  <!-- <el-button
                  <el-button
                    size="medium"
                    type="text"
                    @click="Distributionservice(scope.row)"
                    ><span class="button-textxg"
                      ><i class="el-icon-menu"></i>服务</span
                    ><span class="button-textdx"
                      ><i class="el-icon-s-promotion"></i>短信发送</span
                    ></el-button
                  > -->
                  >
                  <!-- <el-button
                    size="medium"
                    type="text"
@@ -1261,8 +1261,17 @@
        this.loading = false;
      });
    },
    Distributionservice(row) {
      this.serviceVisible = true;
    Distributionservice(patient) {
      this.$store.dispatch("sms/openSmsDialog", {
        name: patient.name,
        age: patient.age,
        phone: patient.telcode,
        deptName: patient.deptName,
        wardName: patient.wardName,
        smsTemplate: `尊敬的${patient.name},您好!`,
      });
      this.$message.success(`已准备向 ${patient.name} å‘送短信`);
    },
    RiskMarker(row) {
      this.RiskVisible = true;
@@ -1671,6 +1680,9 @@
.button-textxga {
  color: #de7897;
}
.button-textdx {
  color: #569655;
}
.button-textxg {
  color: #de7897;
}
src/views/patient/propaganda/QuestionnaireTask.vue
@@ -370,8 +370,7 @@
                  </el-row>
                </el-row>
                <el-row v-if="form.appltype == 4">
                  <el-col :span="20"
                    ><el-form-item label="适用手术" prop="region">
                  <el-form-item label="适用手术" prop="region">
                      <el-select
                        v-model="form.oplevelcode"
                        style="width: 400px"
@@ -389,8 +388,85 @@
                          :value="item.value"
                        >
                        </el-option>
                      </el-select> </el-form-item
                  ></el-col>
                    </el-select>
                  </el-form-item>
                  <div
                    style="
                      margin-bottom: 20px;
                      padding: 8px 12px;
                      background-color: #f0f9ff;
                      border-left: 4px solid #409eff;
                    "
                  >
                    <p
                      style="
                        margin: 0;
                        color: #606266;
                        font-size: 13px;
                        line-height: 1.4;
                      "
                    >
                      <i
                        class="el-icon-info"
                        style="color: #409eff; margin-right: 6px"
                      ></i>
                      é’ˆå¯¹åŒä¸€æ‰‹æœ¯ç±»åž‹åœ¨å¤šç§‘室/病区下存在的情况,可选择性配置固定科室/病区
                    </p>
                  </div>
                  <!-- æ–°å¢žï¼šæ‰‹æœ¯å…³è”下的科室配置(单选) -->
                  <el-row :gutter="20" style="margin-top: 20px">
                    <el-col :span="12">
                      <el-form-item label="关联科室" prop="diseaseDept">
                        <el-select
                          v-model="diseaseDept"
                          style="width: 100%"
                          clearable
                          filterable
                          placeholder="请选择科室(可选)"
                          value-key="deptCode"
                          @change="handleDiseaseDeptChange"
                        >
                          <el-option
                            v-for="item in belongDepts"
                            :key="item.deptCode"
                            :label="item.deptName"
                            :value="item"
                          ></el-option>
                        </el-select>
                        <div v-if="diseaseDept" class="selected-info">
                          å·²é€‰æ‹©: {{ diseaseDept.deptName }} ({{
                            diseaseDept.deptCode
                          }})
                        </div>
                      </el-form-item>
                    </el-col>
                    <el-col :span="12">
                      <el-form-item label="关联病区" prop="diseaseWard">
                        <el-select
                          v-model="diseaseWard"
                          style="width: 100%"
                          clearable
                          filterable
                          placeholder="请选择病区(可选)"
                          value-key="districtCode"
                          @change="handleDiseaseWardChange"
                        >
                          <el-option
                            v-for="item in belongWards"
                            :key="item.districtCode"
                            :label="item.districtName"
                            :value="item"
                          ></el-option>
                        </el-select>
                        <div v-if="diseaseWard" class="selected-info">
                          å·²é€‰æ‹©: {{ diseaseWard.districtName }} ({{
                            diseaseWard.districtCode
                          }})
                        </div>
                      </el-form-item>
                    </el-col>
                  </el-row>
                </el-row>
                <el-row>
                  <el-col :span="12"
@@ -1097,8 +1173,8 @@
      // æ—¶é—´å¤„理
      daytime: [], //日期
      applydaytime: [], //计算日期
      diseaseDept: null, // ç–¾ç—…关联下的科室(存储整个对象)
      diseaseWard: null, // ç–¾ç—…关联下的病区(存储整个对象)
      diseaseDept: null, // ç–¾ç—…或手术关联下的科室(存储整个对象)
      diseaseWard: null, // ç–¾ç—…或手术关联下的病区(存储整个对象)
      diseaseDepts: "",
      diseaseWards: "",
      time1: "", //上午时间段
@@ -1551,12 +1627,12 @@
        }
        // æ ¡éªŒï¼šç–¾ç—…关联科室或病区
        if (this.form.appltype == 3) {
        if (this.form.appltype == 3 || this.form.appltype == 4) {
          const hasDept = this.diseaseDept?.deptCode;
          const hasWard = this.diseaseWard?.districtCode;
          if (!hasDept && !hasWard) {
            this.$modal.msgError("当前疾病需关联科室或病区");
            this.$modal.msgError("需关联科室或病区");
            this.submitLoading = false;
            return;
          }
src/views/patient/propaganda/particty.vue
@@ -389,15 +389,13 @@
                  </el-row>
                </el-row>
                <el-row v-if="form.appltype == 4">
                  <el-col :span="20"
                    ><el-form-item label="适用手术" prop="region">
                  <el-form-item label="适用手术" prop="region">
                      <el-select
                        v-model="operationcodes"
                      v-model="form.oplevelcode"
                        style="width: 400px"
                        @remove-tag="removeopera"
                        :remote-method="remoteopcode"
                        size="medium"
                        multiple
                      :remote-method="remoteopcode"
                        filterable
                        remote
                        placeholder="请选择手术"
@@ -405,13 +403,89 @@
                        <el-option
                          class="ruleFormaa"
                          v-for="item in baseoperaList"
                          :key="item.icdcode"
                          :label="item.icdname"
                          :value="item.icdcode"
                        :label="item.label"
                        :value="item.value"
                        >
                        </el-option>
                      </el-select> </el-form-item
                  ></el-col>
                    </el-select>
                  </el-form-item>
                  <div
                    style="
                      margin-bottom: 20px;
                      padding: 8px 12px;
                      background-color: #f0f9ff;
                      border-left: 4px solid #409eff;
                    "
                  >
                    <p
                      style="
                        margin: 0;
                        color: #606266;
                        font-size: 13px;
                        line-height: 1.4;
                      "
                    >
                      <i
                        class="el-icon-info"
                        style="color: #409eff; margin-right: 6px"
                      ></i>
                      é’ˆå¯¹åŒä¸€æ‰‹æœ¯ç±»åž‹åœ¨å¤šç§‘室/病区下存在的情况,可选择性配置固定科室/病区
                    </p>
                  </div>
                  <!-- æ–°å¢žï¼šæ‰‹æœ¯å…³è”下的科室配置(单选) -->
                  <el-row :gutter="20" style="margin-top: 20px">
                    <el-col :span="12">
                      <el-form-item label="关联科室" prop="diseaseDept">
                        <el-select
                          v-model="diseaseDept"
                          style="width: 100%"
                          clearable
                          filterable
                          placeholder="请选择科室(可选)"
                          value-key="deptCode"
                          @change="handleDiseaseDeptChange"
                        >
                          <el-option
                            v-for="item in belongDepts"
                            :key="item.deptCode"
                            :label="item.deptName"
                            :value="item"
                          ></el-option>
                        </el-select>
                        <div v-if="diseaseDept" class="selected-info">
                          å·²é€‰æ‹©: {{ diseaseDept.deptName }} ({{
                            diseaseDept.deptCode
                          }})
                        </div>
                      </el-form-item>
                    </el-col>
                    <el-col :span="12">
                      <el-form-item label="关联病区" prop="diseaseWard">
                        <el-select
                          v-model="diseaseWard"
                          style="width: 100%"
                          clearable
                          filterable
                          placeholder="请选择病区(可选)"
                          value-key="districtCode"
                          @change="handleDiseaseWardChange"
                        >
                          <el-option
                            v-for="item in belongWards"
                            :key="item.districtCode"
                            :label="item.districtName"
                            :value="item"
                          ></el-option>
                        </el-select>
                        <div v-if="diseaseWard" class="selected-info">
                          å·²é€‰æ‹©: {{ diseaseWard.districtName }} ({{
                            diseaseWard.districtCode
                          }})
                        </div>
                      </el-form-item>
                    </el-col>
                  </el-row>
                </el-row>
                <el-row>
                  <el-col :span="12"
@@ -1039,7 +1113,10 @@
      questionList: [],
      skip: false,
      donorchargeList: [],
      baseoperaList: [],
      baseoperaList: [ { value: "1", label: "一级手术" },
        { value: "2", label: "二级手术" },
        { value: "3", label: "三级手术" },
        { value: "4", label: "四级手术" },],
      selectedOrder: [],
      diseaseDept: null, // ç–¾ç—…关联下的科室(存储整个对象)
      diseaseWard: null, // ç–¾ç—…关联下的病区(存储整个对象)
@@ -1588,7 +1665,7 @@
        }
        // 2. ç–¾ç—…关联科室或病区校验
        if (this.form.appltype == 3) {
        if (this.form.appltype == 3 || this.form.appltype == 4) {
          const hasDept = this.diseaseDept?.deptCode;
          const hasWard = this.diseaseWard?.districtCode;
@@ -2204,24 +2281,24 @@
      }).then((row) => {
        this.donorchargeList = res.rows;
      });
      getbaseopera({
        pageNum: 1,
        pageSize: 1000,
      }).then((row) => {
        this.baseoperaList = res.rows;
      });
      // getbaseopera({
      //   pageNum: 1,
      //   pageSize: 1000,
      // }).then((row) => {
      //   this.baseoperaList = res.rows;
      // });
    },
    // æ‰‹æœ¯æŸ¥è¯¢
    remoteopcode(name) {
      if (name) {
        getbaseopera({
          pageNum: 1,
          pageSize: 1000,
          opdesc: name,
        }).then((res) => {
          this.baseoperaList = res.rows;
        });
      }
      // if (name) {
      //   getbaseopera({
      //     pageNum: 1,
      //     pageSize: 1000,
      //     opdesc: name,
      //   }).then((res) => {
      //     this.baseoperaList = res.rows;
      //   });
      // }
    },
    // ä»»åŠ¡ç§‘å®¤åˆ é™¤è§¦å‘
src/views/repositoryai/templateku/index.vue
@@ -499,7 +499,7 @@
} from "@/api/AiCentre/index";
import { listDept } from "@/api/system/dept";
export default {
  name: "templateku",
  name: "Templateku",
  data() {
    return {
      topactiveName: "Local", //顶部选择
src/views/sfstatistics/percentage/index.vue
@@ -204,7 +204,7 @@
import { getSfStatisticsHyperlink } from "@/api/AiCentre/index";
export default {
  name: "FollowUpStatistics",
  name: "Percentage",
  components: {
    FirstFollowUp,
    SecondFollowUp,
vue.config.js
@@ -37,13 +37,13 @@
      [process.env.VUE_APP_BASE_API]: {
        // target: `https://www.health-y.cn/lssf`,
        // target: `http://192.168.100.10:8096`,
        target: `http://192.168.100.10:8094`,//省立同德
        // target: `http://192.168.100.10:8094`,//省立同德
        // target: `http://192.168.100.10:8095`,//新华
        // target: `http://192.168.100.10:8098`,//市一
        // target:`http://localhost:8095`,
        // target:`http://35z1t16164.qicp.vip`,
        // target: `http://192.168.100.172:8095`,
        // target: `http://192.168.100.10:8089`,//南华
        target: `http://192.168.100.10:8089`,//南华
        // target: `http://192.168.191.181:8095`,
        changeOrigin: true,
        pathRewrite: {
Ëæ·ÃÍâÁ´.zip
copy from "\351\232\217\350\256\277\351\200\232\347\224\250\357\274\210\351\234\200\345\220\214\346\255\245\346\234\200\346\226\260\347\212\266\346\200\201\357\274\211.zip" copy to "\351\232\217\350\256\277\345\244\226\351\223\276.zip" Binary files differ
Ëæ·ÃÍâÁ´Í¨ÓÃ.zip
copy from "\351\232\217\350\256\277\351\200\232\347\224\250\357\274\210\351\234\200\345\220\214\346\255\245\346\234\200\346\226\260\347\212\266\346\200\201\357\274\211.zip" copy to "\351\232\217\350\256\277\345\244\226\351\223\276\351\200\232\347\224\250.zip" Binary files differ
Ëæ·ÃͨÓÃ.zip
copy from "\351\232\217\350\256\277\351\200\232\347\224\250\357\274\210\351\234\200\345\220\214\346\255\245\346\234\200\346\226\260\347\212\266\346\200\201\357\274\211.zip" copy to "\351\232\217\350\256\277\351\200\232\347\224\250.zip" Binary files differ