53f4f0add976a4b402dfc2ad8547056227156693..6f1e7a63fa6afc261ba2247bf1d56f59dbb9f4c9
2025-08-07 WXL
测试完成
6f1e7a 对比 | 目录
2025-08-07 WXL
测试完成
5fba33 对比 | 目录
2025-08-07 WXL
测试完成
209b2f 对比 | 目录
已添加1个文件
已删除1个文件
已修改10个文件
1900 ■■■■■ 文件已修改
src/api/AiCentre/EChartsdata.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/CallButton/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sipService-bd.js 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sipService-xs.js 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sipService.js 299 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/followvisit/discharge/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/education/compilequer/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/patient/patient/hospital.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/patient/propaganda/Missioncreation.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/healthinformation/compilequer/index.vue 713 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/healthinformation/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/AiCentre/EChartsdata.js
@@ -25,6 +25,14 @@
    data: data,
  });
}
// é¦–页中部数据
export function getServiceStatistics(data) {
  return request({
    url: "/smartor/serviceSubtask/getServiceStatistics",
    method: "post",
    data: data,
  });
}
// æŸ¥è¯¢æ‚£è€…住院记录列表
export function getechartsMedInhospList(data) {
  return request({
src/components/CallButton/index.vue
@@ -42,10 +42,10 @@
      callStatus: 'idle', // idle, calling, connected, ended
      sipStatus: "未连接",
      sipStatusClass: "status-disconnected",
     randomNum = Math.floor(Math.random() * 21) + 1000, // ç”Ÿæˆ 1000-1020 çš„随机整数
     randomNum : Math.floor(Math.random() * 11) + 1000, // ç”Ÿæˆ 1000-1010 çš„随机整数
      sipConfig: {
        wsUrl: "wss://192.168.100.6:7443",
        sipUri: `${randomNum}`+"@192.168.100.6",
        wsUrl: "wss://192.168.10.124:7443",
        sipUri: `${randomNum}`+"@192.168.10.124",
        password: "Smartor@2023",
        displayName: "Web å°é¾™",
      },
src/utils/sipService-bd.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,200 @@
import JsSIP from "jssip";
class SipService {
  constructor() {
    this.ua = null;
    this.currentSession = null;
    this.onStatusChange = null; // çŠ¶æ€å˜åŒ–å›žè°ƒ
    this.onCallStatusChange = null; // æ–°å¢žé€šè¯çŠ¶æ€å›žè°ƒ
  }
  // åˆå§‹åŒ–SIP客户端
  init(config) {
    try {
      this.updateStatus("connecting", "连接中...");
      this.ua = new JsSIP.UA({
        sockets: [new JsSIP.WebSocketInterface(config.wsUrl)],
        uri: config.sipUri,
        password: config.password,
        display_name: config.displayName,
        iceservers: [],
        // realm: config.realm,
        register: true,
        session_expires: 180,
        sessionTimersExpires: 300, // è®¾ç½® Session-Expires=120(必须 >= Min-SE)
        extraHeaders: [
          "Min-SE: 120", // å¯é€‰ï¼šæ˜¾å¼å‘Šè¯‰æœåŠ¡å™¨ä½ æ”¯æŒçš„æœ€å°å€¼
        ],
        register_expires: 300, // æ³¨å†Œæœ‰æ•ˆæœŸ(秒)
        connection_recovery_min_interval: 2, // æœ€å°é‡è¿žé—´éš”
        connection_recovery_max_interval: 30, // æœ€å¤§é‡è¿žé—´éš”
      });
      this.ua.start();
      // æ³¨å†Œäº‹ä»¶ç›‘听
      this.ua.on("registered", () => {
        this.updateStatus("registered", "已注册");
      });
      this.ua.on("registrationFailed", (e) => {
        this.updateStatus("failed", `注册失败: ${e.cause}`);
      });
      this.ua.on("disconnected", () => {
        this.updateStatus("disconnected", "连接断开");
      });
      this.ua.on("connected", () => {
        this.updateStatus("connecting", "重新连接中...");
      });
      // ç›‘听来电
      this.ua.on("newRTCSession", (data) => {
        this.handleIncomingCall(data.session);
      });
    } catch (error) {
      this.updateStatus("failed", `初始化失败: ${error.message}`);
      console.error("SIP初始化失败:", error);
    }
  }
  handleIncomingCall(session) {
    if (session.direction === "incoming") {
      console.log("来电:", session.remote_identity.uri.toString());
      // å¯ä»¥åœ¨è¿™é‡Œè§¦å‘ UI é€šçŸ¥
      if (this.onIncomingCall) {
        this.onIncomingCall(session);
      }
    }
  }
  // æ›´æ–°çŠ¶æ€å¹¶é€šçŸ¥UI
  updateStatus(type, text) {
    console.log(`SIP状态更新: ${type} - ${text}`);
    if (this.onStatusChange) {
      this.onStatusChange({ type, text });
    }
  }
  // ä¸€é”®æ‹¨å· - å¢žåŠ æ³¨å†ŒçŠ¶æ€æ£€æŸ¥
  makeCall(targetNumber) {
    if (!this.ua) {
      throw new Error("SIP客户端未初始化");
    }
    if (!this.ua.isRegistered()) {
      throw new Error("SIP未注册,无法呼叫");
    }
    const options = {
      sessionTimers: true,
      sessionTimersExpires: 300,
      extraHeaders: [
        "Min-SE: 120",
        "Route: <sip:@192.168.100.6>",
        "Accept: application/sdp",
        "Supported: replaces, timer",
        "Allow: INVITE, ACK, BYE, CANCEL, OPTIONS",
      ],
      eventHandlers: {
        progress: (e) => {
          this.updateCallStatus("calling", "呼叫中...");
        },
        failed: (e) => {
          this.updateCallStatus("ended", `呼叫失败: ${e.cause}`);
        },
        ended: (e) => {
          this.updateCallStatus("ended", "通话结束");
        },
        confirmed: (e) => {
          this.updateCallStatus("connected", "通话已接通");
        },
      },
      mediaConstraints: {
        audio: true,
        video: false,
      },
      rtcOfferConstraints: {
        offerToReceiveAudio: 1,
        offerToReceiveVideo: 0,
        mandatory: {
          OfferToReceiveAudio: true,
          OfferToReceiveVideo: false,
        },
      },
      pcConfig: {
        iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
        iceTransportPolicy: "all",
        bundlePolicy: "balanced",
        rtcpMuxPolicy: "require",
        codecs: {
          audio: [
            { name: "PCMU", clockRate: 8000, payloadType: 0 },
            { name: "PCMA", clockRate: 8000, payloadType: 8 },
          ],
          video: [],
        },
      },
    };
    this.currentSession = this.ua.call(
      `sip:${targetNumber}@192.168.100.6`,
      options
    );
    // åœ¨ä¼šè¯åˆ›å»ºåŽä¿®æ”¹ SDP
    this.currentSession.on("peerconnection", (pc) => {
       this.updateCallStatus('calling', '呼叫中...');
      pc.createOffer = (offerOptions) => {
        return RTCPeerConnection.prototype.createOffer
          .call(pc, offerOptions)
          .then((offer) => {
            const modifiedSdp = offer.sdp
              .replace(/c=IN IP4 192\.168\.100\.10/g, "c=IN IP4 192.168.100.6")
              .replace(/m=audio \d+ RTP\/AVP.*/, "m=audio 7078 RTP/AVP 0 8");
            return new RTCSessionDescription({
              type: "offer",
              sdp: modifiedSdp,
            });
          });
      };
    });
    this.currentSession.on('failed', (e) => {
        this.updateCallStatus('failed', `呼叫失败2: ${e.cause}`);
      });
      this.currentSession.on('ended', () => {
        this.updateCallStatus('ended', '通话已结束');
      });
      this.currentSession.on('confirmed', () => {
        this.updateCallStatus('connected', '通话已接通');
      });
    this.setupAudio(this.currentSession);
  }
  setupAudio(session) {
    session.connection.addEventListener("addstream", (e) => {
      const audioElement = document.getElementById("remoteAudio");
      if (audioElement) {
        audioElement.srcObject = e.stream;
      }
    });
  }
  // æŒ‚断当前通话
  endCall() {
  if (this.currentSession) {
      this.currentSession.terminate();
      this.updateCallStatus('ended', '通话已结束');
      this.currentSession = null;
    }
  }
  // æ–°å¢žæ–¹æ³•:更新通话状态
  updateCallStatus(type, text) {
    console.log(`通话状态更新: ${type} - ${text}`);
    if (this.onCallStatusChange) {
      this.onCallStatusChange({ type, text });
    }
  }
}
export default new SipService();
src/utils/sipService-xs.js
ÎļþÒÑɾ³ý
src/utils/sipService.js
@@ -4,11 +4,11 @@
  constructor() {
    this.ua = null;
    this.currentSession = null;
    this.onStatusChange = null; // çŠ¶æ€å˜åŒ–å›žè°ƒ
    this.onCallStatusChange = null; // æ–°å¢žé€šè¯çŠ¶æ€å›žè°ƒ
    this.onStatusChange = null;
    this.onCallStatusChange = null;
    this.onIncomingCall = null;
  }
  // åˆå§‹åŒ–SIP客户端
  init(config) {
    try {
      this.updateStatus("connecting", "连接中...");
@@ -18,160 +18,161 @@
        uri: config.sipUri,
        password: config.password,
        display_name: config.displayName,
        iceservers: [],
        // realm: config.realm,
        iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
        register: true,
        session_expires: 180,
        sessionTimersExpires: 300, // è®¾ç½® Session-Expires=120(必须 >= Min-SE)
        extraHeaders: [
          "Min-SE: 120", // å¯é€‰ï¼šæ˜¾å¼å‘Šè¯‰æœåŠ¡å™¨ä½ æ”¯æŒçš„æœ€å°å€¼
        ],
        register_expires: 300, // æ³¨å†Œæœ‰æ•ˆæœŸ(秒)
        connection_recovery_min_interval: 2, // æœ€å°é‡è¿žé—´éš”
        connection_recovery_max_interval: 30, // æœ€å¤§é‡è¿žé—´éš”
        session_expires: 900,
        sessionTimersExpires: 600,
        extraHeaders: ["Min-SE: 120"],
        register_expires: 300,
        connection_recovery_min_interval: 2,
        connection_recovery_max_interval: 30,
        pcConfig: {
          iceTransportPolicy: "all",
          rtcpMuxPolicy: "require",
          bundlePolicy: "max-bundle"
        }
      });
      this.ua.start();
      // æ³¨å†Œäº‹ä»¶ç›‘听
      this.ua.on("registered", () => {
        this.updateStatus("registered", "已注册");
      });
      // äº‹ä»¶ç›‘听
      this.ua.on("registered", () => this.updateStatus("registered", "已注册"));
      this.ua.on("registrationFailed", (e) =>
        this.updateStatus("failed", `注册失败: ${e.cause}`));
      this.ua.on("disconnected", () =>
        this.updateStatus("disconnected", "连接断开"));
      this.ua.on("connected", () =>
        this.updateStatus("connecting", "重新连接中..."));
      this.ua.on("newRTCSession", (data) =>
        this.handleIncomingCall(data.session));
      this.ua.on("registrationFailed", (e) => {
        this.updateStatus("failed", `注册失败: ${e.cause}`);
      });
      this.ua.on("disconnected", () => {
        this.updateStatus("disconnected", "连接断开");
      });
      this.ua.on("connected", () => {
        this.updateStatus("connecting", "重新连接中...");
      });
      // ç›‘听来电
      this.ua.on("newRTCSession", (data) => {
        this.handleIncomingCall(data.session);
      });
    } catch (error) {
      this.updateStatus("failed", `初始化失败: ${error.message}`);
      console.error("SIP初始化失败:", error);
    }
  }
  handleIncomingCall(session) {
    if (session.direction === "incoming") {
      console.log("来电:", session.remote_identity.uri.toString());
      // å¯ä»¥åœ¨è¿™é‡Œè§¦å‘ UI é€šçŸ¥
      if (this.onIncomingCall) {
        this.onIncomingCall(session);
      }
      throw error;
    }
  }
  // æ›´æ–°çŠ¶æ€å¹¶é€šçŸ¥UI
  updateStatus(type, text) {
    console.log(`SIP状态更新: ${type} - ${text}`);
    if (this.onStatusChange) {
      this.onStatusChange({ type, text });
    }
  }
  // ä¸€é”®æ‹¨å· - å¢žåŠ æ³¨å†ŒçŠ¶æ€æ£€æŸ¥
  makeCall(targetNumber) {
    if (!this.ua) {
      throw new Error("SIP客户端未初始化");
    }
    return new Promise((resolve, reject) => {
      try {
        if (!this.ua) {
          throw new Error("SIP客户端未初始化");
        }
    if (!this.ua.isRegistered()) {
      throw new Error("SIP未注册,无法呼叫");
    }
        if (!this.ua.isRegistered()) {
          throw new Error("SIP未注册,无法呼叫");
        }
    const options = {
      sessionTimers: true,
      sessionTimersExpires: 300,
      extraHeaders: [
        "Min-SE: 120",
        "Route: <sip:@192.168.100.6>",
        "Accept: application/sdp",
        "Supported: replaces, timer",
        "Allow: INVITE, ACK, BYE, CANCEL, OPTIONS",
      ],
      eventHandlers: {
        progress: (e) => {
          this.updateCallStatus("calling", "呼叫中...");
        },
        failed: (e) => {
          this.updateCallStatus("ended", `呼叫失败: ${e.cause}`);
        },
        ended: (e) => {
          this.updateCallStatus("ended", "通话结束");
        },
        confirmed: (e) => {
          this.updateCallStatus("connected", "通话已接通");
        },
      },
      mediaConstraints: {
        audio: true,
        video: false,
      },
      rtcOfferConstraints: {
        offerToReceiveAudio: 1,
        offerToReceiveVideo: 0,
        mandatory: {
          OfferToReceiveAudio: true,
          OfferToReceiveVideo: false,
        },
      },
      pcConfig: {
        iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
        iceTransportPolicy: "all",
        bundlePolicy: "balanced",
        rtcpMuxPolicy: "require",
        codecs: {
          audio: [
            { name: "PCMU", clockRate: 8000, payloadType: 0 },
            { name: "PCMA", clockRate: 8000, payloadType: 8 },
        const options = {
          sessionTimers: false, // æš‚时禁用以减少兼容性问题
          extraHeaders: [
            "Min-SE: 120",
            "Accept: application/sdp",
            "Supported: outbound"
          ],
          video: [],
        },
      },
    };
          mediaConstraints: { audio: true, video: false },
          rtcOfferConstraints: {
            offerToReceiveAudio: true,
            offerToReceiveVideo: false
          },
          eventHandlers: {
            progress: () => this.updateCallStatus("calling", "呼叫中..."),
            failed: (e) => {
              this.handleCallFailure(e, reject);
            },
            ended: () => this.updateCallStatus("ended", "通话结束"),
            confirmed: () => {
              this.updateCallStatus("connected", "通话已接通");
              resolve();
            }
          }
        };
    this.currentSession = this.ua.call(
      `sip:${targetNumber}@192.168.100.6`,
      options
    );
    // åœ¨ä¼šè¯åˆ›å»ºåŽä¿®æ”¹ SDP
    this.currentSession.on("peerconnection", (pc) => {
       this.updateCallStatus('calling', '呼叫中...');
      pc.createOffer = (offerOptions) => {
        return RTCPeerConnection.prototype.createOffer
          .call(pc, offerOptions)
          .then((offer) => {
            const modifiedSdp = offer.sdp
              .replace(/c=IN IP4 192\.168\.100\.10/g, "c=IN IP4 192.168.100.6")
              .replace(/m=audio \d+ RTP\/AVP.*/, "m=audio 7078 RTP/AVP 0 8");
            return new RTCSessionDescription({
              type: "offer",
              sdp: modifiedSdp,
            });
          });
        this.currentSession = this.ua.call(
          `sip:${targetNumber}@192.168.10.124`,
          options
        );
        this.setupPeerConnection(this.currentSession);
        this.setupAudio(this.currentSession);
      } catch (error) {
        this.updateCallStatus("failed", `呼叫失败1: ${error.message}`);
        reject(error);
      }
    });
  }
  setupPeerConnection(session) {
    session.on("peerconnection", (pc) => {
      const originalCreateOffer = pc.createOffer.bind(pc);
      pc.createOffer = async (offerOptions) => {
        try {
          const offer = await originalCreateOffer(offerOptions);
          return this.normalizeSDP(offer);
        } catch (error) {
          console.error("创建Offer失败:", error);
          throw error;
        }
      };
    });
    this.currentSession.on('failed', (e) => {
        this.updateCallStatus('failed', `呼叫失败2: ${e.cause}`);
      });
      this.currentSession.on('ended', () => {
        this.updateCallStatus('ended', '通话已结束');
      });
      this.currentSession.on('confirmed', () => {
        this.updateCallStatus('connected', '通话已接通');
      });
    this.setupAudio(this.currentSession);
  }
  normalizeSDP(offer) {
    let sdp = offer.sdp;
    // 1. æ ‡å‡†åŒ–连接行
    sdp = sdp.replace(/c=IN IP4.*\r\n/, "c=IN IP4 0.0.0.0\r\n");
    // 2. æ ‡å‡†åŒ–音频媒体行
    sdp = sdp.replace(/m=audio \d+.*\r\n/,
      "m=audio 9 UDP/TLS/RTP/SAVPF 0 8\r\n");
    // 3. ç¡®ä¿åŒ…含基本编解码器
    if (!sdp.includes("PCMU/8000")) {
      sdp += "a=rtpmap:0 PCMU/8000\r\n";
    }
    if (!sdp.includes("PCMA/8000")) {
      sdp += "a=rtpmap:8 PCMA/8000\r\n";
    }
    // 4. æ·»åŠ å¿…è¦å±žæ€§
    sdp += "a=rtcp-mux\r\n";
    sdp += "a=sendrecv\r\n";
    console.log("标准化后的SDP:", sdp);
    return new RTCSessionDescription({
      type: offer.type,
      sdp: sdp
    });
  }
  handleCallFailure(e, reject) {
    console.error("呼叫失败详情:", {
      cause: e.cause,
      message: e.message,
      response: e.response && e.response.status_code
    });
    let errorMessage = "呼叫失败";
    switch(e.cause) {
      case "Incompatible SDP":
        errorMessage = "媒体协商失败,请检查编解码器配置";
        break;
      case "488":
      case "606":
        errorMessage = "对方设备不支持当前媒体配置";
        break;
      default:
        errorMessage = `呼叫失败: ${e.cause || e.message}`;
    }
    this.updateCallStatus("failed2", errorMessage);
    reject(new Error(errorMessage));
  }
  setupAudio(session) {
    session.connection.addEventListener("addstream", (e) => {
      const audioElement = document.getElementById("remoteAudio");
@@ -180,21 +181,37 @@
      }
    });
  }
  // æŒ‚断当前通话
  endCall() {
  if (this.currentSession) {
    if (this.currentSession) {
      this.currentSession.terminate();
      this.updateCallStatus('ended', '通话已结束');
      this.updateCallStatus("ended", "通话已结束");
      this.currentSession = null;
    }
  }
  // æ–°å¢žæ–¹æ³•:更新通话状态
  updateStatus(type, text) {
    console.log(`SIP状态更新: ${type} - ${text}`);
    if (this.onStatusChange) {
      this.onStatusChange({ type, text });
    }
  }
  updateCallStatus(type, text) {
    console.log(`通话状态更新: ${type} - ${text}`);
    if (this.onCallStatusChange) {
      this.onCallStatusChange({ type, text });
    }
  }
  handleIncomingCall(session) {
    if (session.direction === "incoming") {
      console.log("来电:", session.remote_identity.uri.toString());
      if (this.onIncomingCall) {
        this.onIncomingCall(session);
      }
    }
  }
}
export default new SipService();
src/views/followvisit/discharge/index.vue
@@ -126,6 +126,12 @@
            placeholder="请输入主治医生"
          ></el-input>
        </el-form-item>
        <el-form-item label="经管医生" prop="managementDoctor">
          <el-input
            v-model="topqueryParams.managementDoctor"
            placeholder="请输入主治医生"
          ></el-input>
        </el-form-item>
        <el-form-item label="患者范围" prop="status">
          <el-cascader
@@ -437,6 +443,13 @@
          align="center"
          key="updateBy"
          prop="updateBy"
          width="120"
        />
        <el-table-column
          label="经管医生"
          align="center"
          key="managementDoctor"
          prop="managementDoctor"
          width="120"
        />
        <el-table-column
@@ -1397,6 +1410,7 @@
    affiliation() {
      this.topqueryParams.drcode = store.getters.hisUserId;
      this.topqueryParams.nurseId = store.getters.hisUserId;
      this.topqueryParams.managementDoctor = store.getters.name;
      this.getList(1);
    },
    onthatday() {
src/views/index.vue
@@ -105,13 +105,13 @@
                ></el-radio-button>
              </el-radio-group>
            </div>
            <!-- ä¸­é—´echars -->
            <!-- ä¸­éƒ¨çº¿æ€§æŸ±çж图 -->
            <div class="boxEchars">
              <div class="echars1" id="echars"></div>
            </div>
          </div>
        </el-col>
        <!-- ä¸­é—´å’Œå³è¾¹ -->
        <!-- å³è¾¹åˆ—表 -->
        <el-col :span="4" class="aside">
          <div class="grid-content bg-purple" style="margin-top: -180px">
            <div class="title">
@@ -134,9 +134,7 @@
                ></el-table-column>
                <el-table-column prop="rc" class-name="rc">
                  <template slot-scope="scope">
                    {{ scope.row.rc }}次
                  </template>
                  <template slot-scope="scope"> {{ scope.row.rc }}次 </template>
                </el-table-column>
              </el-table>
            </div>
@@ -292,7 +290,7 @@
  getechartsListCountdata,
  getechartsMedOuthospList,
  getechartsMedInhospList,
  getechartsandData,
  getServiceStatistics,
  getDeptRanking,
} from "@/api/AiCentre/index";
import dayjs from "dayjs";
@@ -310,6 +308,11 @@
      lastHeight: window.innerHeight,
      radio1: "月",
      ticketStatistics: {},
      timeTypeMap: {
        å‘¨: "day",
        æœˆ: "month",
        å¹´: "year",
      },
      DischargeData: {
        rs: "",
        rc: "",
@@ -352,7 +355,7 @@
    this.getgraphdata();
    this.getranking();
    this.$nextTick(function () {
      this.getregionAmountCollect();
      this.myEcharts2();
      this.getnodeCollect();
      this.getSkuTop();
    });
@@ -379,7 +382,7 @@
      this.getgraphdata();
      this.getranking();
      this.getTopdata();
      this.getregionAmountCollect();
      this.myEcharts2();
      this.getnodeCollect();
      this.getSkuTop();
    },
@@ -396,15 +399,15 @@
    },
    // top排行
    async getSkuTop() {
       let Rankingdata = {
      let Rankingdata = {
        startDate: this.endatd,
        endDate: this.statd,
        cy: 1,
      };
      await getDeptRanking(Rankingdata).then((res) => {
        if (res.code == 200) {
          this.SkuTop=res.rows.sort((a, b) => b.rc - a.rc);
          console.log(this.SkuTop,'this.SkuTop');
          this.SkuTop = res.rows.sort((a, b) => b.rc - a.rc);
          console.log(this.SkuTop, "this.SkuTop");
        }
      });
@@ -451,26 +454,141 @@
        }
      });
    },
    // èŽ·å–å°±è¯Šæ•°é‡
    getranking() {
    },
    // èŽ·å–ä¸­éƒ¨çº¿æŸ±å›¾æ•°æ®
    getgraphdata() {
      let Outhospdata = {
    getranking() {},
    async getgraphdata() {
      let params = {
        startDate: this.endatd,
        endDate: this.statd,
        cy: 1,
        timeType:
          this.radio1 === "周"
            ? "day"
            : this.radio1 === "月"
            ? "month"
            : "year",
      };
      let Inhospdata = {
        startDate: this.endatd,
        endDate: this.statd,
        cy: 1,
      try {
        const res = await getServiceStatistics(params);
        if (res.code === 200) {
          this.processChartData(res.data);
        }
      } catch (error) {
        console.error("获取图表数据失败:", error);
      }
    },
    processChartData(data) {
      // æŒ‰æ—¶é—´æŽ’序确保数据顺序正确
      const sortedData = [...data].sort(
        (a, b) => new Date(a.timePeriod) - new Date(b.timePeriod)
      );
      const xAxisData = [];
      const dischargeFollowData = [];
      const outpatientFollowData = [];
      const pmiData = [];
      const pmoData = [];
      sortedData.forEach((item) => {
        // æ ¹æ®æ—¶é—´ç±»åž‹æ ¼å¼åŒ–显示
        let timeLabel = item.timePeriod;
        if (this.radio1 === "周") {
          timeLabel = dayjs(item.timePeriod).format("MM-DD");
        } else if (this.radio1 === "月") {
          timeLabel = item.timePeriod.split("-")[1] + "月";
        } else {
          timeLabel = item.timePeriod.split("-")[0] + "å¹´";
        }
        xAxisData.push(timeLabel);
        dischargeFollowData.push(item.dischargeFollowCount);
        outpatientFollowData.push(item.outpatientFollowCount);
        pmiData.push(item.pmiCount);
        pmoData.push(item.pmoCount);
      });
      // æ›´æ–°å›¾è¡¨
      this.updateChart(
        xAxisData,
        dischargeFollowData,
        outpatientFollowData,
        pmiData,
        pmoData
      );
    },
    updateChart(
      xAxisData,
      dischargeFollowData,
      outpatientFollowData,
      pmiData,
      pmoData
    ) {
      if (!this.myChart2) {
        this.myEcharts2();
        return;
      }
      // è®¡ç®—随访量的最大值
      const maxFollow = Math.max(
        ...dischargeFollowData,
        ...outpatientFollowData
      );
      // è®¡ç®—服务人次的最大值
      const maxService = Math.max(...pmiData, ...pmoData);
      // åŠ¨æ€è®¡ç®—interval值
      const followInterval = this.calculateOptimalInterval(maxFollow);
      const serviceInterval = this.calculateOptimalInterval(maxService);
      const option = {
        xAxis: {
          data: xAxisData,
        },
        yAxis: [
          {
            interval: followInterval,
            max: Math.ceil(maxFollow / followInterval) * followInterval,
          },
          {
            interval: serviceInterval,
            max: Math.ceil(maxService / serviceInterval) * serviceInterval,
          },
        ],
        series: [
          { data: dischargeFollowData },
          { data: outpatientFollowData },
          { data: pmiData },
          { data: pmoData },
        ],
      };
      getechartsMedOuthospList(Outhospdata).then((res) => {});
      getechartsMedInhospList(Inhospdata).then((res) => {});
      this.myChart2.setOption(option);
    },
    // è®¡ç®—最优的interval值
    calculateOptimalInterval(maxValue) {
      if (maxValue <= 0) return 50; // é»˜è®¤å€¼
      // æ ¹æ®æœ€å¤§å€¼è®¡ç®—合适的间隔
      const magnitude = Math.pow(10, Math.floor(Math.log10(maxValue)));
      const stepRatio = maxValue / magnitude;
      let interval;
      if (stepRatio > 5) {
        interval = magnitude;
      } else if (stepRatio > 2) {
        interval = magnitude / 2;
      } else {
        interval = magnitude / 5;
      }
      // ç¡®ä¿interval是整数
      interval = Math.round(interval);
      // é™åˆ¶æœ€å°é—´éš”
      return Math.max(interval, 50);
    },
    // èŽ·å–çº¿çŠ¶å›¾æ—¶é—´
    async getregionAmountCollect() {
      //getregionAmountCollect(1, this.endatd, this.statd);
@@ -480,11 +598,12 @@
      this.series = [123, 123, 223, 212, 432, 123, 442, 234];
      this.myEcharts2();
    },
    // çº¿æ€§å›¾
    // çº¿æ€§å›¾åŠæŸ±çж图
    myEcharts2() {
      var echarts = require("echarts");
      var myChart2 = echarts.init(document.getElementById("echars"));
      this.myChart2 = myChart2;
      var option2 = {
        tooltip: {
          trigger: "axis",
@@ -504,30 +623,12 @@
          },
        },
        legend: {
          data: [
            "出院随访量",
            "门诊随访量",
            // "在院随访量",
            // "门诊复诊通知",
            "出院服务人次",
            "门诊服务人次",
          ],
          data: ["出院随访量", "门诊随访量", "出院服务人次", "门诊服务人次"],
        },
        xAxis: [
          {
            type: "category",
            data: [
              "一月",
              "二月",
              "三月",
              "四月",
              "五月",
              "六月",
              "七月",
              "八月",
              "九月",
              "十月",
            ],
            data: [], // åˆå§‹ä¸ºç©ºï¼Œå°†é€šè¿‡API数据填充
            axisPointer: {
              type: "shadow",
            },
@@ -538,18 +639,14 @@
            type: "value",
            name: "随访量",
            min: 0,
            max: 250,
            interval: 50,
            axisLabel: {
              formatter: "{value} äºº",
            },
          },
          {
            type: "value",
            name: "复诊/评估次数",
            name: "服务人次",
            min: 0,
            max: 250,
            interval: 50,
            axisLabel: {
              formatter: "{value} æ¬¡",
            },
@@ -565,18 +662,8 @@
                return value + " äºº";
              },
            },
            data: [120, 150, 165, 90, 140, 200, 130, 85, 175, 95, 110, 160],
            data: [], // åˆå§‹ä¸ºç©ºï¼Œå°†é€šè¿‡API数据填充
          },
          // {
          //   name: "影像随访量",
          //   type: "bar",
          //   tooltip: {
          //     valueFormatter: function (value) {
          //       return value + " äºº";
          //     },
          //   },
          //   data: [102, 190, 135, 88, 175, 160, 83, 145, 200, 110, 97, 180],
          // },
          {
            name: "门诊随访量",
            type: "bar",
@@ -585,21 +672,8 @@
                return value + " äºº";
              },
            },
            data: [145, 92, 178, 134, 167, 85, 199, 112, 156, 88, 120, 145],
            data: [], // åˆå§‹ä¸ºç©ºï¼Œå°†é€šè¿‡API数据填充
          },
          // {
          //   name: "出院复诊通知",
          //   type: "line",
          //   smooth: 0.3,
          //   yAxisIndex: 1,
          //   tooltip: {
          //     valueFormatter: function (value) {
          //       return value + " æ¬¡";
          //     },
          //   },
          //   data: [45, 123, 78, 156, 89, 34, 199, 112, 67, 145, 88, 175],
          // },
          {
            name: "出院服务人次",
            type: "line",
@@ -610,7 +684,7 @@
                return value + " æ¬¡";
              },
            },
            data: [102, 190, 135, 88, 175, 160, 83, 145, 200, 110, 97, 180],
            data: [], // åˆå§‹ä¸ºç©ºï¼Œå°†é€šè¿‡API数据填充
          },
          {
            name: "门诊服务人次",
@@ -622,29 +696,15 @@
                return value + " æ¬¡";
              },
            },
            data: [120, 150, 165, 90, 140, 200, 130, 85, 175, 95, 110, 160],
            data: [], // åˆå§‹ä¸ºç©ºï¼Œå°†é€šè¿‡API数据填充
          },
        ],
      };
      myChart2.on("updateAxisPointer", function (event) {
        const xAxisInfo = event.axesInfo[0];
        if (xAxisInfo) {
          const dimension = xAxisInfo.value + 1;
          myChart2.setOption({
            series: {
              id: "pie",
              label: {
                formatter: "{b}: {@[" + dimension + "]} ",
              },
              encode: {
                value: dimension,
                tooltip: dimension,
              },
            },
          });
        }
      });
      myChart2.setOption(option2);
      // åˆå§‹åŠ è½½æ•°æ®
      this.getgraphdata();
    },
    // é¥¼çж图
    myPieChart() {
src/views/knowledge/education/compilequer/index.vue
@@ -703,7 +703,7 @@
        });
      }
      // å®£æ•™åˆ†ç±»
      getheLibraryAssort({}).then((res) => {
      getheLibraryAssort({ hetype: 1 }).then((res) => {
        this.sortlist = res.rows;
        console.log(this.sortlist);
      });
src/views/patient/patient/hospital.vue
@@ -268,6 +268,13 @@
            width="120"
          />
          <el-table-column
            label="经管医生"
            align="center"
            key="managementDoctor"
            prop="managementDoctor"
            width="120"
          />
          <el-table-column
            label="主治医生"
            align="center"
            key="drname"
src/views/patient/propaganda/Missioncreation.vue
@@ -124,7 +124,7 @@
                      </el-select> </el-form-item
                  ></el-col>
                </el-row>
                    <el-form-item label="执行周期" prop="longTask">
                <el-form-item label="执行周期" prop="longTask">
                  <el-radio-group v-model="form.longTask">
                    <el-radio :label="0">自定义周期</el-radio>
                    <el-radio :label="1">长期任务</el-radio>
@@ -147,7 +147,10 @@
                    <el-radio :label="2">即刻发送</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item label="执行日期:" v-if="form.sendType == 1&& !form.longTask">
                <el-form-item
                  label="执行日期:"
                  v-if="form.sendType == 1 && !form.longTask"
                >
                  <el-date-picker
                    v-model="daytime"
                    @change="changeTimeday"
@@ -160,7 +163,10 @@
                  </el-date-picker>
                </el-form-item>
                <el-form-item label="执行时间点:" v-if="form.sendType == 3&& !form.longTask">
                <el-form-item
                  label="执行时间点:"
                  v-if="form.sendType == 3 && !form.longTask"
                >
                  <div style="display: flex">
                    <div style="margin-right: 10px">
                      <el-date-picker
@@ -175,7 +181,10 @@
                  </div>
                </el-form-item>
                <el-form-item label="执行时间段:" v-if="form.sendType == 1&& !form.longTask">
                <el-form-item
                  label="执行时间段:"
                  v-if="form.sendType == 1 && !form.longTask"
                >
                  <div style="display: flex">
                    <div style="margin-right: 10px">
                      <span style="font-size: 18px; margin-right: 10px">①</span>
@@ -406,7 +415,6 @@
                        icon="el-icon-upload2"
                        size="medium"
                        @click="handleImport"
                        >导入</el-button
                      >
                    </el-col>
@@ -530,11 +538,19 @@
    <!-- æ¨¡æ¿é¢„览 -->
    <el-dialog title="模板预览" :visible.sync="previewtf" width="60%">
      <div class="preview-left">
        <!-- å•选 -->
        <div v-html="htmlRichText"></div>
        <!-- æ ¹æ®æ¨¡æ¿ç±»åž‹æ˜¾ç¤ºä¸åŒå†…容 -->
        <div v-if="currentTemplateType == '2'">
          <!-- é€šçŸ¥æ¨¡æ¿åªæ˜¾ç¤ºçº¯æ–‡æœ¬å†…容 -->
          <div style="white-space: pre-wrap; font-size: 16px; line-height: 1.6">
            {{ plainTextContent }}
          </div>
        </div>
        <div v-else>
          <!-- å…¶ä»–类型模板显示富文本内容 -->
          <div v-html="htmlRichText"></div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <!-- <el-button @click="previewGo">前往模板详情修改</el-button> -->
        <el-button type="primary" @click="previewFn">确认使用</el-button>
      </span>
    </el-dialog>
@@ -606,13 +622,16 @@
        <el-table :data="uploadingData" style="width: 100%">
          <el-table-column prop="serial" label="患者id"> </el-table-column>
          <el-table-column prop="name" label="姓名"
          width="100"> </el-table-column>
          <el-table-column prop="sex" label="性别"width="100"> </el-table-column>
          <el-table-column prop="idcardno" width="300" label="证件号码"> </el-table-column>
          <el-table-column prop="name" label="姓名" width="100">
          </el-table-column>
          <el-table-column prop="sex" label="性别" width="100">
          </el-table-column>
          <el-table-column prop="idcardno" width="300" label="证件号码">
          </el-table-column>
          <el-table-column prop="goday" label="出生日期"> </el-table-column>
          <el-table-column prop="telcode" width="200" label="联系方式"> </el-table-column>
          <el-table-column prop="createTime"  width="200" label="创建日期">
          <el-table-column prop="telcode" width="200" label="联系方式">
          </el-table-column>
          <el-table-column prop="createTime" width="200" label="创建日期">
          </el-table-column>
        </el-table>
        <!-- <pagination
@@ -653,26 +672,20 @@
              <el-form-item label="宣教名称">
                <el-input v-model="topqueryParams.preachname"></el-input>
              </el-form-item>
              <el-form-item label="宣教分类" prop="region">
              <el-form-item label="宣教类型" prop="region">
                <el-select
                  v-model="topqueryParams.assortid"
                  v-model="topqueryParams.hetype"
                  size="medium"
                  filterable
                  placeholder="请选择分类"
                >
                  <el-option-group
                    v-for="group in sortlist"
                    :key="group.id"
                    :label="group.assortname"
                  <el-option
                    v-for="item in heLibraryAssortList"
                    :key="item.id"
                    :label="item.value"
                    :value="item.id"
                  >
                    <el-option
                      v-for="item in group.heLibraryAssortList"
                      :key="item.id"
                      :label="item.assortname"
                      :value="item.id"
                    >
                    </el-option>
                  </el-option-group>
                  </el-option>
                </el-select>
              </el-form-item>
@@ -767,6 +780,8 @@
    return {
      title: "宣教内容列表",
      currenttype: 1, //1宣教2门诊3出院4复诊5体检6问卷
      currentTemplateType: "", // å½“前模板类型
      plainTextContent: "", // çº¯æ–‡æœ¬å†…容
      id: "", //
      previewid: "", //任务模板传递id
      libName: "",
@@ -816,7 +831,7 @@
      tableLabelxj: [
        { label: "创建人", width: "", prop: "createBy" },
        { label: "宣教名称", width: "180", prop: "preachname" },
        { label: "宣教描述", width: "180", prop: "preachcontent" },
        { label: "宣教内容", width: "180", prop: "preachcontent" },
        // { label: "宣教形式", width: "", prop: "playType" },
        { label: "适用方式", width: "", prop: "suitway" },
        { label: "修改日期", width: "", prop: "uploadTime" },
@@ -930,6 +945,10 @@
      ],
      variableListTime: [],
      sortlist: [],
      heLibraryAssortList: [
        { id: 1, value: "宣教" },
        { id: 2, value: "通知" },
      ],
      tasktopic: null, //新增类型
      SelectPatientslist: [],
      form: {
@@ -939,7 +958,10 @@
        templatename: "",
        templateid: null,
        libtemplateid: null,
        kcb: "亲爱的患者-家属,我们是"+localStorage.getItem("orgname")+"的医护人员,为了更好地了解您的康复情况,请您抽一点宝贵时间,观看这份宣教资讯。",
        kcb:
          "亲爱的患者-家属,我们是" +
          localStorage.getItem("orgname") +
          "的医护人员,为了更好地了解您的康复情况,请您抽一点宝贵时间,观看这份宣教资讯。",
        jsy: "生活上要劳逸结合,注意休息和营养,适当锻炼,戒烟限酒,保持心情舒畅,定期复诊。那本次宣教内容就到这里,祝您身体健康!",
      },
      taskoptions: [
@@ -1104,7 +1126,7 @@
    submitForm(formName) {
      this.form.preachform = this.checkList.join(",");
      // this.formatFn(1);
      if (!this.form.patTaskRelevances[0]) {
      if (!this.form.patTaskRelevances[0]&&this.form.longTask==0) {
        this.$modal.msgError("请选择病人");
        return;
      }
@@ -1122,7 +1144,7 @@
        this.form.isoperation = 2;
      } else {
        this.form.isoperation = 1;
        this.form.sendState=1;
        this.form.sendState = 1;
      }
      if (!this.form.type) {
        this.form.type = this.$route.query.type;
@@ -1150,28 +1172,33 @@
    // ----------------------表格子组件事件
    // é€‰æ‹©æ¨¡æ¿å¹¶é¢„览
    selectfn(row, type) {
      // æ¨¡æ¿æƒ…况下获取模板信息
      this.libName = row.preachname;
      this.htmlRichText = null;
      this.libId = row.id;
      console.log(row, "row");
      this.Tasktemplate = row;
      // è®¾ç½®å½“前模板类型
      this.currentTemplateType = row.hetype || "1"; // é»˜è®¤ä¸ºå®£æ•™ç±»åž‹
      this.previewtf = true;
      this.previewid = row.svyid;
      console.log(this.questionList, "questionList");
      // this.Variablehandling(row.svyLibScripts, 1);
      console.log(row.htmlRichText);
      axios
        .get(row.htmlRichText)
        .then((response) => {
          console.log(response.data, "数据"); // è¾“出获取到的文件内容
          this.htmlRichText = response.data;
          this.htmlRichText = this.addStyleToImages(this.htmlRichText);
        })
        .catch((error) => {
          this.$modal.msgError("获取富文本失败");
          console.error("Failed to fetch file:", error);
        });
      if (this.currentTemplateType == "2") {
        // å¦‚果是通知模板,获取纯文本内容
        this.plainTextContent = row.preachcontent;
      } else {
        // å…¶ä»–类型模板获取富文本内容
        axios
          .get(row.htmlRichText)
          .then((response) => {
            this.htmlRichText = response.data;
            this.htmlRichText = this.addStyleToImages(this.htmlRichText);
          })
          .catch((error) => {
            this.$modal.msgError("获取富文本失败");
            console.error("Failed to fetch file:", error);
          });
      }
    },
    // é¢„览模板
    previewfnm() {
@@ -1182,16 +1209,24 @@
        this.Tasktemplate = res.rows[0];
        this.previewtf = true;
        this.previewid = res.rows[0].svyid;
        axios
          .get(res.rows[0].htmlRichText)
          .then((response) => {
            this.htmlRichText = response.data;
            this.htmlRichText = this.addStyleToImages(this.htmlRichText);
          })
          .catch((error) => {
            this.$modal.msgError("获取富文本失败");
            console.error("Failed to fetch file:", error);
          });
        this.currentTemplateType = res.rows[0].hetype || "1"; // é»˜è®¤ä¸ºå®£æ•™ç±»åž‹
        if (this.currentTemplateType == "2") {
          // å¦‚果是通知模板,获取纯文本内容
          this.plainTextContent = res.rows[0].preachcontent;
        } else {
          // å…¶ä»–类型模板获取富文本内容
          axios
            .get(res.rows[0].htmlRichText)
            .then((response) => {
              this.htmlRichText = response.data;
              this.htmlRichText = this.addStyleToImages(this.htmlRichText);
            })
            .catch((error) => {
              this.$modal.msgError("获取富文本失败");
              console.error("Failed to fetch file:", error);
            });
        }
      });
    },
    addStyleToImages(html) {
@@ -1274,7 +1309,7 @@
    handleExport() {},
    // é€‰æ‹©æ‚£è€…表数据
    handleSelectionChange(selection,type) {
    handleSelectionChange(selection, type) {
      console.log("多选患者");
      this.SelectPatientslist = selection;
      this.multiple = !selection.length;
@@ -1289,8 +1324,8 @@
            item.sfzh = item.idcardno;
          }
          if (type) {
            item.hospType=type
          }else{
            item.hospType = type;
          } else {
            item.hospType = this.patientqueryParams.allhosp;
          }
          this.overallCase.push(item);
@@ -1368,7 +1403,10 @@
        templateid: null,
        libtemplateid: null,
        serviceType: Number(this.$route.query.serviceType),
        kcb: "亲爱的患者-家属,我们是"+localStorage.getItem("orgname")+"的医护人员,为了更好地了解您的康复情况,请您抽一点宝贵时间,完成这份随访问卷。",
        kcb:
          "亲爱的患者-家属,我们是" +
          localStorage.getItem("orgname") +
          "的医护人员,为了更好地了解您的康复情况,请您抽一点宝贵时间,观看这份宣教资讯。",
        jsy: "生活上要劳逸结合,注意休息和营养,适当锻炼,戒烟限酒,保持心情舒畅,定期复诊。那本次回访就到这里,祝您身体健康!",
      };
@@ -1601,9 +1639,9 @@
        this.$refs.upload.submit();
        this.dractive++;
      } else if (this.dractive == 2) {
        this.handleSelectionChange(this.uploadingData,4);
        this.handleSelectionChange(this.uploadingData, 4);
        this.upload.open = false;
        this.dractive = 1
        this.dractive = 1;
      }
    },
@@ -1754,6 +1792,23 @@
    }
  }
}
/* æ–°å¢žæ ·å¼ */
.preview-left {
  padding: 20px;
  max-height: 70vh;
  overflow-y: auto;
}
/* çº¯æ–‡æœ¬å†…容样式 */
.plain-text-content {
  white-space: pre-wrap;
  font-size: 16px;
  line-height: 1.6;
  padding: 15px;
  background: #f9f9f9;
  border-radius: 4px;
}
.download {
  text-align: center;
  .el-upload__tip {
src/views/shortmessage/healthinformation/compilequer/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="Questionnairemanagement">
  <div class="NotificationManagement">
    <!-- å·¦ä¾§æ  -->
    <div class="sidecolumn">
      <el-steps finish-status="success" :active="Editprogress" simple>
@@ -10,13 +10,6 @@
            >
          </template>
        </el-step>
        <el-step>
          <template slot="title">
            <span style="cursor: pointer" @click="Editprogress = 2"
              >通知内容</span
            >
          </template>
        </el-step>
      </el-steps>
    </div>
    <!-- å³ä¾§æ•°æ® -->
@@ -24,6 +17,7 @@
      <!-- åŸºæœ¬ä¿¡æ¯ -->
      <div v-if="Editprogress == 1">
        <div class="leftvlue-jbxx">基本信息</div>
        <el-divider></el-divider>
        <el-form
          :model="ruleForm"
          :rules="rules"
@@ -58,20 +52,20 @@
            <el-col :span="12"> </el-col>
          </el-row>
          <el-form-item label="通知标题" prop="preachname">
            <div style="width: 30%">
            <div style="width: 60%">
              <el-input
                v-model="ruleForm.preachname"
                placeholder="请输入标题"
              ></el-input>
            </div>
          </el-form-item>
          <el-form-item label="通知描述" prop="preachcontent">
            <div style="width: 60%">
          <el-form-item label="通知内容" prop="preachcontent">
            <div style="width: 80%">
              <el-input
                type="textarea"
                :rows="2"
                :rows="5"
                v-model="ruleForm.preachcontent"
                placeholder="请输入描述"
                placeholder="请输入通知内容"
              ></el-input>
            </div>
          </el-form-item>
@@ -109,21 +103,6 @@
            </div>
          </el-form-item>
          <el-form-item label="文件" prop="sickness">
            <div style="width: 40%">
              <el-upload
                class="upload-demo"
                action="https://jsonplaceholder.typicode.com/posts/"
                :on-change="handleChange"
                :file-list="fileList"
              >
                <el-button size="small" type="primary">点击上传</el-button>
                <div slot="tip" class="el-upload__tip">
                  åªèƒ½ä¸Šä¼ jpg/png/xsl文件,且不超过50mb
                </div>
              </el-upload>
            </div>
          </el-form-item>
          <el-form-item label="标签" prop="desc">
            <div class="xinz-inf">
              <el-tag
@@ -142,6 +121,7 @@
                @change="handleInputConfirm"
                filterable
                remote
                allow-create
                reserve-keyword
                default-first-option
                :remote-method="remoteMethodtag"
@@ -175,53 +155,23 @@
            ></el-col>
            <el-col :span="9">
              <el-form-item label="可用状态" prop="region">
                <el-select
                  v-model="ruleForm.isavailable"
                  size="medium"
                  filterable
                  placeholder="请选择分类"
                >
                  <el-option
                    class="ruleFormaa"
                    v-for="item in usable"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                <el-radio-group v-model="ruleForm.isAvailable">
                  <el-radio
                    v-for="(item, index) in usable"
                    :label="item.value"
                    >{{ item.label }}</el-radio
                  >
                  </el-option>
                </el-select> </el-form-item
            ></el-col>
                </el-radio-group>
              </el-form-item></el-col
            >
          </el-row>
          <el-form-item label="通知方式" prop="region">
            <el-select
              v-model="ruleForm.suitway"
              size="medium"
              multiple
              filterable
              placeholder="请选择分类"
            >
              <el-option
                class="ruleFormaa"
                v-for="item in mode"
                :key="item.label"
                :label="item.label"
                :value="item.label"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <!-- <el-form-item label="适用疾病" prop="region">
            <el-button type="warning" @click="$refs.child.handleAddpatient()"
              >添加疾病</el-button
            >
          </el-form-item> -->
          <el-form-item label="适用院区" prop="region">
            <el-select
              v-model="ruleForm.campus"
              size="medium"
              multiple
              filterable
              placeholder="请选择分类"
              placeholder="请选择院区"
            >
              <el-option
                class="ruleFormaa"
@@ -248,105 +198,12 @@
            </el-cascader>
          </el-form-item>
          <el-form-item>
            <el-button type="success" @click="nextstep('ruleForm')"
              >下一步</el-button
            >
            <el-button type="success" @click="Departmenttreatment('ruleForm')"
              >保存</el-button
            >
            <el-button type="info" @click="closeFm('ruleForm')">关闭</el-button>
          </el-form-item>
        </el-form>
      </div>
      <!-- é€šçŸ¥å†…容 -->
      <div v-if="Editprogress == 2">
        <el-row :gutter="20">
          <el-col :span="4"><div class="leftvlue-jbxx">通知内容</div></el-col>
        </el-row>
        <div>
          <el-form
            :model="ruleForm"
            :rules="rules"
            ref="ruleForm"
            label-width="100px"
            class="demo-ruleForm"
          >
            <el-row gutter="20">
              <el-col :span="12">
                <el-form-item label="资料形式" prop="region">
                  <el-select
                    v-model="ruleForm.shape"
                    placeholder="请选择内容形式"
                  >
                    <el-option
                      v-for="item in xjxsoptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <div>
                  <el-button @click="laststep('ruleForm')">上一步</el-button>
                  <el-button
                    type="success"
                    @click="Departmenttreatment('ruleForm')"
                    >保存</el-button
                  >
                  <el-button
                    type="warning"
                    @click="Departmenttreatment('ruleForm')"
                    >另存新版本</el-button
                  >
                  <el-button type="info" @click="closeFm('ruleForm')"
                    >关闭</el-button
                  >
                </div></el-col
              >
            </el-row>
          </el-form>
        </div>
        <div>
          <el-upload
            class="upload-demo"
            :action="uploadImgUrlword"
            :on-success="uploadEditorSuccessword"
            :on-error="uploadEditorErrorword"
            :before-upload="beforeEditorUploadword"
            :headers="headers"
          >
            <el-button size="small" type="primary">word文件上传</el-button>
          </el-upload>
          <div id="quillEditorQiniu">
            <!-- åŸºäºŽelementUi的上传组件 el-upload begin-->
            <el-upload
              class="avatar-uploader"
              :action="uploadImgUrl"
              :accept="'image/*,video/*'"
              :show-file-list="false"
              :on-success="uploadEditorSuccess"
              :on-error="uploadEditorError"
              :before-upload="beforeEditorUpload"
              :headers="headers"
            >
            </el-upload>
            <!-- åŸºäºŽelementUi的上传组件 el-upload end-->
            <quill-editor
              class="editor"
              v-model="content"
              ref="customQuillEditor"
              :options="editorOption"
              @blur="onEditorBlur"
              @focus="onEditorFocus"
              @change="onEditorChange"
            >
            </quill-editor>
          </div>
        </div>
      </div>
    </div>
    <!-- æ·»åŠ é€‚ç”¨ç–¾ç—…çª—å£ -->
@@ -361,9 +218,7 @@
</template>
<script>
import { quillEditor } from "vue-quill-editor";
import axios from "axios";
import {
  getheLibraryAssort,
  delheLibraryAssort,
@@ -379,115 +234,33 @@
  illnesslistget,
  getillness,
} from "@/api/AiCentre/index";
import OptionalForm from "@/components/OptionalForm"; //正则组件
import OptionalForm from "@/components/OptionalForm";
import { listDept } from "@/api/system/dept";
// import * as Quill from "quill";
import Quill from "quill";
import { listtag } from "@/api/system/label";
import store from "@/store";
// è¿™é‡Œå¼•入修改过的video模块并注册
import Video from "./video";
Quill.register(Video, true);
//获取登录token,引入文件,如果只是简单测试,没有上传文件是否登录的限制的话,
//这个token可以不用获取,文件可以不引入,把上面对应的上传文件携带请求头  :headers="headers" è¿™ä¸ªä»£ç åˆ æŽ‰å³å¯
import { getToken } from "@/utils/auth";
const toolbarOptions = [
  ["bold", "italic", "underline", "strike"], // toggled buttons
  ["blockquote", "code-block"],
  [{ header: 1 }, { header: 2 }], // custom button values
  [{ list: "ordered" }, { list: "bullet" }],
  [{ script: "sub" }, { script: "super" }], // superscript/subscript
  [{ indent: "-1" }, { indent: "+1" }], // outdent/indent
  [{ direction: "rtl" }], // text direction
  [{ size: ["small", false, "large", "huge"] }], // custom dropdown
  [{ header: [1, 2, 3, 4, 5, 6, false] }],
  [{ color: [] }, { background: [] }], // dropdown with defaults from theme
  [{ font: [] }],
  [{ align: [] }],
  ["link", "image", "video"],
  ["clean"], // remove formatting button
];
export default {
  name: "NotificationManagement",
  components: { OptionalForm },
  data() {
    return {
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload",
      uploadImgUrlword: process.env.VUE_APP_BASE_API + "/common/uploadShow",
      uploadUrlPath: "没有文件上传",
      quillUpdateImg: false,
      fileList: [
        {
          name: "food.jpeg",
          url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
        },
        {
          name: "food2.jpeg",
          url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
        },
      ],
      content: "", //最终保存的内容
      fileName: "", //文件名
      dynamicTags: [],
      inputVisible: false,
      illnessVisible: false,
      dialogVisiblepatient: false, //适用疾病窗口
      dialogVisiblepatient: false,
      inputValue: "",
      // å¯Œæ–‡æœ¬
      editorOption: {
        placeholder: "你想说什么?",
        modules: {
          imageResize: {
            displayStyles: {
              backgroundColor: "black",
              border: "none",
              color: "white",
            },
            modules: ["Resize", "DisplaySize", "Toolbar"],
          },
          toolbar: {
            container: toolbarOptions, // å·¥å…·æ 
            handlers: {
              image: function (value) {
                if (value) {
                  document
                    .querySelector("#quillEditorQiniu .avatar-uploader input")
                    .click();
                } else {
                  this.quill.format("image", false);
                }
              },
              video: function (value) {
                if (value) {
                  document
                    .querySelector("#quillEditorQiniu .avatar-uploader input")
                    .click();
                } else {
                  this.quill.format("video", false);
                }
              },
            },
          },
        },
      },
      sidecolumnrabs: "left", //方向
      Editprogress: 1, //编辑进度
      currentVersion: "1.2.3", //当前版本
      loading: false, // é®ç½©å±‚
      drawer: false, //控制展开
      radio: "false", //单选题选中
      radios: [], //多选题选中
      radioas: "", //填空题答案
      // æ€»æ¡æ•°
      sidecolumnrabs: "left",
      Editprogress: 1,
      currentVersion: "1.2.3",
      loading: false,
      drawer: false,
      radio: "false",
      radios: [],
      radioas: "",
      total: 1,
      hetype: "",
      id: null,
@@ -513,42 +286,24 @@
      deptList: [],
      tempDetpRelevanceslist: [],
      props: { multiple: true, value: "deptId", label: "deptName" },
      xjxsoptions: [
        {
          value: "1",
          label: "图文",
        },
        {
          value: "2",
          label: "视频",
        },
        {
          value: "3",
          label: "音频",
        },
      ],
      valssu: [
        {
          idd: 1,
          wssd: "你最近怎么样",
          sdadd: ["sss", "ssccss", "ssaas", "ss"],
        },
      ],
      addvalue: "添加题目",
      variablelist: [
        { variatename: "姓名", variate: "${name}", default: 1 },
        { variatename: "电话", variate: "${phone}", default: 1 },
        { variatename: "病情", variate: "${illness}", default: 1 },
      ],
      // æŸ¥è¯¢å‚æ•°
      queryParams: {
        pageNum: 1,
        pageSize: 10,
      },
    };
  },
  activated() {
    if (this.id != this.$route.query.id) {
      this.gettabList();
      this.getList();
      this.illnessUpdate();
    }
  },
  created() {
    this.gettabList();
    this.getList();
@@ -559,18 +314,7 @@
    this.precedencetype = store.getters.precedencetype;
    this.courtyardlist = store.getters.courtyardlist;
  },
  watch: {
    content(newVal, oldVal) {
      //this.$emit('input', newVal);
      console.log(newVal, "A");
      console.log(oldVal, "B");
    },
  },
  methods: {
    processElement(element) {
      return { ...element, isoperation: null };
    },
    // èŽ·å–é¡µé¢æ•°æ®
    getList() {
      this.loading = true;
@@ -579,16 +323,13 @@
      if (this.id) {
        getlibraryinfo({ id: this.id }).then((res) => {
          this.ruleForm = res.data[0];
          this.ruleForm.campus = this.ruleForm.campus.split(",");
          if (this.ruleForm.campus)
            this.ruleForm.campus = this.ruleForm.campus.split(",");
          this.dynamicTags = res.data[0].heLibraryTagList.map(
            this.processElement
          );
          this.Getmissioncontent(this.ruleForm.richText);
          if (this.ruleForm.deptNames) {
            this.tempDetpRelevanceslist = JSON.parse(this.ruleForm.deptNames);
          }
          if (this.ruleForm.suitway) {
            this.ruleForm.suitway = this.ruleForm.suitway.split(",");
          }
          this.variablelist = this.ruleForm.otherdata
            ? JSON.parse(this.ruleForm.otherdata)
@@ -598,51 +339,46 @@
      // é€šçŸ¥åˆ†ç±»
      getheLibraryAssort({ hetype: 2 }).then((res) => {
        this.sortlist = res.rows;
        console.log(this.sortlist);
      });
      // éƒ¨é—¨
      listDept(this.queryParams).then((response) => {
        this.deptList = this.handleTree(response.data, "deptId");
      });
      this.loading = false;
    },
    processElement(element) {
      return { ...element, isoperation: null };
    },
    submitForm(formName) {
      let tgs = [];
      this.dynamicTags.forEach((item) => {
        tgs.push(item.tagname);
      });
      this.ruleForm.campus = this.ruleForm.campus.join(",");
      if (this.ruleForm.campus) {
        this.ruleForm.campus = this.ruleForm.campus.join(",");
      }
      this.ruleForm.labelInfo = tgs.length != 0 ? tgs.join(", ") : "";
      this.ruleForm.otherdata = JSON.stringify(this.variablelist);
      this.ruleForm.hetype = 2;
      console.log(22);
      this.ruleForm.suitway =
        this.ruleForm.suitway.length != 0
          ? this.ruleForm.suitway.join(",")
          : "";
      this.ruleForm.hetype = 2; // é€šçŸ¥ç±»åž‹
      addrichText({
        content: this.content,
        fileName: this.fileName ? this.fileName : "测试.html",
      }).then((res) => {
        this.ruleForm.richText = res.msg;
        if (this.id) {
          this.ruleForm.isoperation = 2;
          compilelibrary(this.ruleForm).then((res) => {
      if (this.id) {
        this.ruleForm.isoperation = 2;
        compilelibrary(this.ruleForm).then((res) => {
          if (res.code == 200) {
            this.$modal.msgSuccess("编辑成功");
            this.confirmillness();
            this.$router.go(-1);
          });
        } else {
          this.ruleForm.isoperation = 1;
          compilelibrary(this.ruleForm).then((res) => {
          }
        });
      } else {
        this.ruleForm.isoperation = 1;
        compilelibrary(this.ruleForm).then((res) => {
          if (res.code == 200) {
            this.$modal.msgSuccess("新增成功");
            this.confirmillness(res.data);
            this.$router.go(-1);
          });
        }
      });
          }
        });
      }
    },
    // ä¿å­˜ç–¾ç—…
    confirmillness(guid) {
@@ -650,7 +386,6 @@
        if (guid) {
          item.outid = guid;
        } else {
          console.log(this.ruleForm);
          item.outid = this.ruleForm.id;
        }
        item.icd10name = item.icdname;
@@ -662,20 +397,6 @@
      });
      this.illnessVisible = false;
      this.$modal.msgSuccess("编辑成功");
    },
    getFileNameFromPath(path) {
      const parts = path.split("/");
      return parts[parts.length - 1];
    },
    // ä¸‹ä¸€æ­¥
    nextstep() {
      if (this.Editprogress <= 1) {
        return this.Editprogress++;
      }
    },
    // ä¸Šä¸€æ­¥
    laststep() {
      this.Editprogress = this.Editprogress - 1;
    },
    // å…³é—­
    closeFm() {
@@ -707,7 +428,6 @@
        );
        if (!condition) {
          listDept({ deptId: item }).then((res) => {
            console.log("dept");
            res.data[0].type = 2;
            this.ruleForm.tempDetpRelevances.push(res.data[0]);
          });
@@ -724,12 +444,7 @@
      setTimeout(() => {
        this.submitForm();
      }, 1000);
      // this.submitForm();
    },
    // ä¿å­˜é¢˜ç›®ä¿¡æ¯
    Saveproblem() {},
    /** æŸ¥è¯¢é¢˜ç›®åˆ—表 */
    // æ–°å¢žå˜é‡
    addvariable() {
      this.variablelist.push({
@@ -741,16 +456,12 @@
    delvariable(item) {
      const index = this.variablelist.indexOf(item);
      if (index !== -1) {
        this.variablelist.splice(index, 1); // ä»Žç´¢å¼•位置删除一个元素
        this.variablelist.splice(index, 1);
      } else {
        console.log("未找到该对象");
      }
    },
    // æŽ§åˆ¶æ–‡ä»¶
    handleChange(file, fileList) {
      this.fileList = fileList.slice(-3);
    },
    // æ ‡ç­¾-----------------
    // æ ‡ç­¾ç›¸å…³æ–¹æ³•
    gettabList() {
      const tagqueryParams = {
        pageNum: 1,
@@ -762,11 +473,9 @@
      });
    },
    handleClosetag(tag) {
      console.log(tag);
      const lindex = this.ruleForm.heLibraryTagList.findIndex(
        (item) => item.tagname == tag.tagname
      );
      console.log(lindex);
      this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
      this.ruleForm.heLibraryTagList[lindex].isoperation = 3;
    },
@@ -812,7 +521,7 @@
    showInput() {
      this.inputVisible = true;
    },
    // ç–¾ç—…-----------------------
    // ç–¾ç—…相关方法
    illnessUpdate() {
      if (this.id) {
        getillness({ outid: this.$route.query.id, type: 6 }).then((res) => {
@@ -823,9 +532,6 @@
        });
      }
    },
    // --------------------------
    // é¢„览模板
    PreviewTemplate() {
      this.drawer = true;
@@ -833,129 +539,12 @@
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    //上传图片之前async
    beforeEditorUpload(res, file) {
      //显示上传动画
      this.quillUpdateImg = true;
      //  const res1 = await uploadImage()
      // console.log(res1,'=====');
      // this.$emit('before',res, file)
      console.log(res);
      console.log(file);
    },
    // ä¸Šä¼ å›¾ç‰‡æˆåŠŸ
    uploadEditorSuccess(res, file) {
      console.log("上传成功");
      // this.$emit('upload',res, file)
      console.log(res, file);
      //拼接出上传的图片在服务器的完整地址
      let imgUrl = res.url;
      let type = imgUrl.substring(imgUrl.lastIndexOf(".") + 1);
      console.log(type);
      // èŽ·å–å¯Œæ–‡æœ¬ç»„ä»¶å®žä¾‹
      let quill = this.$refs.customQuillEditor.quill;
      // èŽ·å–å…‰æ ‡æ‰€åœ¨ä½ç½®
      let length = quill.getSelection().index;
      // æ’入图片||视频  res.info为服务器返回的图片地址
      if (type == "mp4" || type == "MP4") {
        window.jsValue = imgUrl;
        quill.insertEmbed(length, "video", imgUrl);
      } else {
        quill.insertEmbed(length, "image", imgUrl);
      }
      // è°ƒæ•´å…‰æ ‡åˆ°æœ€åŽ
      quill.setSelection(length + 1);
      //取消上传动画
      this.quillUpdateImg = false;
    },
    // å¤±åŽ»ç„¦ç‚¹äº‹ä»¶
    onEditorBlur(e) {
      console.log("onEditorBlur: ", e);
    },
    // èŽ·å¾—ç„¦ç‚¹äº‹ä»¶
    onEditorFocus(e) {
      console.log("onEditorFocus: ", e);
    },
    // å†…容改变事件
    onEditorChange(e) {
      console.log("onEditorChange: ", e);
    },
    // ä¸Šä¼ (文件)图片失败
    uploadEditorError(res, file) {
      console.log(res, "word");
      console.log(file, "word");
      //页面提示
      this.$message.error("上传图片失败");
      //取消上传动画
      this.quillUpdateImg = false;
    },
    //上传组件返回的结果
    uploadResult: function (res) {
      this.uploadUrlPath = res;
    },
    // ä¸Šä¼ (文件)图片失败
    uploadEditorErrorword(res, file) {
      console.log(res);
      console.log(file);
      //页面提示
      this.$message.error("上传图片失败");
      //取消上传动画
      this.quillUpdateImg = false;
    },
    //上传图片之前async
    beforeEditorUploadword(res, file) {
      //显示上传动画
      this.quillUpdateImg = true;
      //  const res1 = await uploadImage()
      // console.log(res1,'=====');
      // this.$emit('before',res, file)
      console.log(res);
      console.log(file);
    },
    // ä¸Šä¼ å›¾ç‰‡æˆåŠŸ
    uploadEditorSuccessword(res, file) {
      console.log("上传成功");
      const data = null;
      console.log(res, file, "word");
      axios
        .get(res.url)
        .then((response) => {
          console.log(response.data, "数据"); // è¾“出获取到的文件内容
          this.content = response.data;
          this.texturl = res.url;
          this.fileName = this.getFileNameFromPath(res.url);
        })
        .catch((error) => {
          console.error("Failed to fetch file:", error);
        });
    },
    Getmissioncontent(url) {
      axios
        .get(url)
        .then((response) => {
          console.log(response.data, "数据"); // è¾“出获取到的文件内容
          this.content = response.data;
          this.fileName = this.getFileNameFromPath(res.url);
        })
        .catch((error) => {
          console.error("Failed to fetch file:", error);
        });
    },
  },
};
</script>
<style lang="scss" scoped>
.Questionnairemanagement {
  // display: flex;
}
.sidecolumn {
  // width: 300px;
  // min-height: 100vh;
  // text-align: center;
  //   display: flex;
  //   margin-top: 20px;
  margin: 20px;
  margin-bottom: 0;
  padding: 20px;
@@ -964,47 +553,34 @@
  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
    0 0 6px 0 rgba(0, 0, 0, 0.04);
}
.leftvlue {
  //   display: flex;
  //   flex: 1;
  margin: 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;
  }
  .leftvlue-jbxx {
    margin-bottom: 50px;
    font-size: 20px;
    span {
      position: absolute;
      right: 80px;
    }
  }
  .demo-cascader {
    margin-right: 20px;
  }
  .PreviewTemplate {
    color: #02a7f0;
    cursor: pointer;
    font-size: 20px;
    margin: 0 20px;
    font-size: 24px;
    height: 30px;
    border-left: 3px solid #41a1be;
    padding-left: 3px;
  }
}
.xinz-inf {
  font-size: 18px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 48px;
  .el-tag + .el-tag {
    margin-left: 10px;
  }
  .button-new-tag {
    margin-left: 10px;
    height: 32px;
@@ -1012,176 +588,41 @@
    padding-top: 0;
    padding-bottom: 0;
  }
  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }
}
.preview-left {
  margin: 20px;
  //   margin: 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);
  .topic-dev {
    margin-bottom: 25px;
    font-size: 20px !important;
    .dev-text {
      margin-bottom: 10px;
    }
  }
}
.addtopic {
  margin-top: 30px;
}
.presentation {
  margin: 20px 0;
  display: flex;
  .presentation-left {
    width: 50%;
    height: 500px;
    .button-textxg {
      color: #024df0;
    }
    .button-textsc {
      color: #f52727;
    }
  }
  .presentation-right {
    width: 50%;
    height: 500px;
    padding: 20px;
    font-size: 18px;
    border: 1px solid #909091;
    span {
      padding: 0 35px;
      margin-right: 10px;
      border-bottom: 1px solid #909091;
    }
    .headline {
      font-size: 20px;
      border-left: 3px solid #41a1be;
      padding-left: 5px;
      margin: 15px 0;
    }
  }
}
::v-deep .addtopic-input {
  input {
    background: #02a7f0;
    color: #edf1f7;
    width: 150px;
  }
}
::v-deep.el-step.is-vertical .el-step__title {
::v-deep .el-step.is-vertical .el-step__title {
  font-size: 25px;
}
::v-deep.el-input--medium {
  font-size: 18px !important;
}
::v-deep.ruleFormaa.el-select {
  display: inline-block;
  position: relative;
  width: 700px;
}
.el-select__tags {
::v-deep.el-select__tags {
  font-size: 20px;
  max-width: 888px !important;
}
::v-deep.el-radio__inner {
  width: 22px;
  height: 22px;
}
// ::v-deep.topic-dev.el-radio__label {
//   font-size: 24px;
// }
::v-deep.el-radio-group {
  span {
    font-size: 24px;
  }
}
::v-deep.el-checkbox-group {
  span {
    font-size: 24px;
  }
}
.editor {
  line-height: normal !important;
  height: 600px;
  margin-bottom: 80px;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}
.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
</style>
src/views/shortmessage/healthinformation/index.vue
@@ -141,7 +141,6 @@
                  icon="el-icon-plus"
                  size="medium"
                  @click="handleAdd"
                  v-hasPermi="['system:user:add']"
                  >新增</el-button
                >
              </el-col>