WXL (wul)
16 小时以前 6e413d95d035e6d798f62fde7964287e1d2fa416
测试完成
已添加2个文件
已修改3个文件
1927 ■■■■ 文件已修改
src/components/SortCheckbox/index.vue 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sipService-cs.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/education/compilequer/index copy.vue 1321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/education/compilequer/index.vue 415 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/patient/propaganda/QuestionnaireTask.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/SortCheckbox/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,165 @@
<template>
  <div class="ordered-checkbox-container">
    <!-- æ¨ªå‘排列的多选框组 -->
    <el-checkbox-group
      v-model="checkedValues"
      class="horizontal-checkbox-group"
    >
      <el-checkbox
        v-for="option in options"
        :key="getValue(option)"
        :label="getValue(option)"
      >
        {{ getLabel(option) }}
      </el-checkbox>
    </el-checkbox-group>
    <!-- é€‰ä¸­é¡ºåºå±•示区域 -->
    <div v-if="selectedOrder.length > 0" class="selection-order-display">
      <span class="order-label">服务执行顺序:</span>
      <span
        v-for="(value, index) in selectedOrder"
        :key="value"
        class="order-item"
      >
        {{ getSelectedIndex(index) }}.{{ getLabelByValue(value) }}
        <span v-if="index < selectedOrder.length - 1">、</span>
      </span>
    </div>
    <div v-else class="selection-order-display">
      <span class="order-label">暂无选中项</span>
    </div>
  </div>
</template>
<script>
export default {
  name: "OrderedCheckboxGroup",
  props: {
    options: {
      type: Array,
      default: () => [],
    },
    value: {
      type: Array,
      default: () => [],
    },
    valueKey: {
      type: String,
      default: "value",
    },
    labelKey: {
      type: String,
      default: "label",
    },
  },
  data() {
    return {
      checkedValues: [],
      selectedOrder: [],
    };
  },
  watch: {
    value: {
      immediate: true,
      handler(newVal) {
        if (JSON.stringify(newVal) !== JSON.stringify(this.checkedValues)) {
          this.checkedValues = [...newVal];
          this.selectedOrder = [...newVal];
        }
      },
    },
    checkedValues(newVal, oldVal) {
      const added = newVal.filter((item) => !oldVal.includes(item));
      const removed = oldVal.filter((item) => !newVal.includes(item));
      added.forEach((value) => {
        if (!this.selectedOrder.includes(value)) {
          this.selectedOrder.push(value);
        }
      });
      removed.forEach((value) => {
        const index = this.selectedOrder.indexOf(value);
        if (index > -1) {
          this.selectedOrder.splice(index, 1);
        }
      });
      this.$emit("input", [...newVal]);
      this.$emit("change", [...newVal], [...this.selectedOrder]);
    },
  },
  methods: {
    getValue(option) {
      return typeof option === "object" ? option[this.valueKey] : option;
    },
    getLabel(option) {
      return typeof option === "object" ? option[this.labelKey] : option;
    },
    getLabelByValue(value) {
      const option = this.options.find(
        (opt) => this.getValue(opt) === value
      );
      return option ? this.getLabel(option) : value;
    },
    getSelectedIndex(index) {
      if (index < 20) {
        return String.fromCharCode(0x2460 + index);
      } else {
        return `(${index + 1})`;
      }
    },
    getSelectionOrder() {
      return [...this.selectedOrder];
    },
    setSelectionOrder(orderedValues) {
      this.selectedOrder = [...orderedValues];
      this.checkedValues = [...orderedValues];
    },
  },
};
</script>
<style scoped>
.ordered-checkbox-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.horizontal-checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.selection-order-display {
  padding: 12px;
  background-color: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}
.order-label {
  font-weight: bold;
  color: #606266;
  margin-right: 8px;
}
.order-item {
  color: #409eff;
  font-weight: 500;
}
/* å“åº”式设计:小屏幕时换行 */
@media (max-width: 768px) {
  .horizontal-checkbox-group {
    gap: 12px;
  }
  .selection-order-display {
    padding: 8px;
  }
}
</style>
src/utils/sipService-cs.js
@@ -93,7 +93,7 @@
      sessionTimersExpires: 300,
      extraHeaders: [
        "Min-SE: 120",
        "Route: <sip:@192.168.100.6>",
        "Route: <sip:@192.168.10.124>",
        "Accept: application/sdp",
        "Supported: replaces, timer",
        "Allow: INVITE, ACK, BYE, CANCEL, OPTIONS",
@@ -140,7 +140,7 @@
    };
    this.currentSession = this.ua.call(
      `sip:${targetNumber}@192.168.100.6`,
      `sip:${targetNumber}@192.168.10.124`,
      options
    );
    // åœ¨ä¼šè¯åˆ›å»ºåŽä¿®æ”¹ SDP
@@ -151,7 +151,7 @@
          .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(/c=IN IP4 192\.168\.100\.10/g, "c=IN IP4 192.168.10.124")
              .replace(/m=audio \d+ RTP\/AVP.*/, "m=audio 7078 RTP/AVP 0 8");
            return new RTCSessionDescription({
              type: "offer",
src/views/knowledge/education/compilequer/index copy.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1321 @@
<template>
  <div class="Questionnairemanagement">
    <!-- å·¦ä¾§æ  -->
    <div class="sidecolumn">
      <el-steps finish-status="success" :active="Editprogress" simple>
        <el-step>
          <template slot="title">
            <span style="cursor: pointer" @click="Editprogress = 1"
              >基础信息设置</span
            >
          </template>
        </el-step>
        <el-step>
          <template slot="title">
            <span style="cursor: pointer" @click="Editprogress = 2"
              >宣教内容</span
            >
          </template>
        </el-step>
      </el-steps>
    </div>
    <!-- å³ä¾§æ•°æ® -->
    <div class="leftvlue">
      <!-- åŸºæœ¬ä¿¡æ¯ -->
      <div v-if="Editprogress == 1">
        <div class="leftvlue-jbxx">基本信息</div>
        <el-divider></el-divider>
        <el-form
          :model="ruleForm"
          :rules="rules"
          ref="ruleForm"
          label-width="100px"
          class="demo-ruleForm"
        >
          <el-form-item label="宣教分类" prop="region">
            <el-select
              v-model="ruleForm.assortid"
              size="medium"
              filterable
              placeholder="请选择分类"
            >
              <el-option-group
                v-for="group in sortlist"
                :key="group.id"
                :label="group.assortname"
              >
                <el-option
                  v-for="item in group.heLibraryAssortList"
                  :key="item.id"
                  :label="item.assortname"
                  :value="item.id"
                >
                </el-option>
              </el-option-group>
            </el-select>
          </el-form-item>
          <el-row>
            <el-col :span="12"> </el-col>
            <el-col :span="12"> </el-col>
          </el-row>
          <el-form-item label="宣教标题" prop="preachname">
            <div style="width: 30%">
              <el-input
                v-model="ruleForm.preachname"
                placeholder="请输入标题"
              ></el-input>
            </div>
          </el-form-item>
          <el-form-item label="宣教描述" prop="preachcontent">
            <div style="width: 60%">
              <el-input
                type="textarea"
                :rows="2"
                v-model="ruleForm.preachcontent"
                placeholder="请输入描述"
              ></el-input>
            </div>
          </el-form-item>
          <el-form-item label="通知变量" prop="name">
            <div style="margin-bottom: 5px" v-for="item in variablelist">
              <el-row>
                <el-col :span="5">
                  <el-input
                    v-model="item.variatename"
                    placeholder="请输入变量名"
                  ></el-input>
                </el-col>
                <el-col :span="8" :offset="1">
                  <el-input
                    v-model="item.variate"
                    placeholder="请输入变量内容"
                  ></el-input>
                </el-col>
                <el-col :span="8" :offset="1">
                  <el-button
                    type="success"
                    icon="el-icon-plus"
                    circle
                    @click="addvariable(item)"
                  ></el-button>
                  <el-button
                    v-if="!item.default"
                    type="danger"
                    icon="el-icon-delete"
                    circle
                    @click="delvariable(item)"
                  ></el-button>
                </el-col>
              </el-row>
            </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
                :key="tag.tagname"
                type="success"
                v-for="tag in dynamicTags"
                closable
                :disable-transitions="false"
                @close="handleClosetag(tag)"
              >
                {{ tag.tagname }}
              </el-tag>
              <el-select
                v-model="inputValue"
                v-if="inputVisible"
                @change="handleInputConfirm"
                filterable
                remote
                allow-create
                reserve-keyword
                default-first-option
                :remote-method="remoteMethodtag"
                :loading="loading"
                placeholder="请选择"
              >
                <el-option
                  v-for="item in optionstag"
                  :key="item.tagid"
                  :label="item.tagname"
                  :value="item.tagname"
                >
                </el-option>
              </el-select>
              <el-button
                v-else
                class="button-new-tag"
                size="small"
                @click="showInput"
                >+ æ–°å¢žæ ‡ç­¾</el-button
              >
            </div>
          </el-form-item>
          <el-row :gutter="20">
            <el-col :span="6">
              <el-form-item label="版本号" prop="name">
                <el-input
                  v-model="ruleForm.version"
                  placeholder="默认1.0.1"
                ></el-input> </el-form-item
            ></el-col>
            <el-col :span="9">
              <el-form-item label="可用状态" prop="region">
                <el-radio-group v-model="ruleForm.isAvailable">
                  <el-radio
                    v-for="(item, index) in usable"
                    :label="item.value"
                    >{{ item.label }}</el-radio
                  >
                </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="请选择分类"
            >
              <el-option
                class="ruleFormaa"
                v-for="item in courtyardlist"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="适用科室" prop="region">
            <el-cascader
              v-model="tempDetpRelevanceslist"
              :options="deptList"
              :props="props"
              :show-all-levels="false"
              clearable
            >
              <template slot-scope="{ node, data }">
                <span>{{ data.deptName }}</span>
                <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
              </template>
            </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-col :offset="16" :span="4">
            <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>
          </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"> -->
            <!-- </el-col>
            </el-row> -->
          </el-form>
        </div>
        <!-- <div>
          <div id="quillEditorQiniu">
            <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>
            <quill-editor
              class="editor"
              v-model="content"
              ref="customQuillEditor"
              :options="editorOption"
              @blur="onEditorBlur"
              @focus="onEditorFocus"
              @change="onEditorChange"
            >
            </quill-editor>
          </div>
        </div> -->
        <!-- æ–°ç»„ä»¶ -->
        <div style="border: 1px solid #ccc; margin: 10px">
          <Toolbar
            style="border-bottom: 1px solid #ccc"
            :editor="editor"
            :defaultConfig="toolbarConfig"
            :mode="modes"
          />
          <Editor
            style="height: 500px; overflow-y: hidden"
            v-model="content"
            :defaultConfig="editorConfig"
            :mode="modes"
            @onCreated="onCreated"
          />
        </div>
        <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>
      </div>
    </div>
    <!-- æ·»åŠ é€‚ç”¨ç–¾ç—…çª—å£ -->
    <Optional-Form
      ref="child"
      :dialogVisiblepatient="dialogVisiblepatient"
      :overallCase="illnesslist"
      @addoption="dialogVisiblepatient = false"
      @kkoption="dialogVisiblepatient = true"
    />
  </div>
</template>
<script>
import { quillEditor } from "vue-quill-editor";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import axios from "axios";
import {
  getheLibraryAssort,
  delheLibraryAssort,
  addheLibraryAssort,
  addtargetillness,
  getlibrarylist,
  dellibraryinfo,
  deltargetillness,
  compilelibrary,
  addrichText,
  getlibraryinfo,
  getillnesslist,
  illnesslistget,
  getillness,
} from "@/api/AiCentre/index";
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: "aEducationinfo",
  components: { OptionalForm, Editor, Toolbar },
  data() {
    return {
      editor: null,
      content: "<p>hello</p>",
      toolbarConfig: {},
      editorConfig: {
        placeholder: "请输入内容...",
        menus: [
          "head",
          "bold",
          "italic",
          "underline",
          "image",
          "link",
          "list",
          "undo",
          "redo",
          "file", // æ·»åŠ è‡ªå®šä¹‰æ–‡ä»¶ä¸Šä¼ èœå•
        ],
        uploadImgServer: process.env.VUE_APP_BASE_API + "/common/uploadSort", // å›¾ç‰‡ä¸Šä¼ æŽ¥å£
        uploadImgHeaders: {
          Authorization: "Bearer " + getToken(),
        }, // è‡ªå®šä¹‰ä¸Šä¼ çš„ headers
        uploadImgParams: { key: "value" }, // è‡ªå®šä¹‰ä¸Šä¼ çš„参数
        uploadImgMaxSize: 2 * 1024 * 1024, // å›¾ç‰‡æœ€å¤§å¤§å°ï¼Œå•位 Byte
        uploadImgMaxLength: 1, // ä¸€æ¬¡æœ€å¤šä¸Šä¼ å›¾ç‰‡æ•°é‡
        uploadImgTimeout: 3 * 60 * 1000, // è¶…时时间,单位 ms
        uploadImgHooks: {
          customInsert: (insertImgFn, result) => {
            const url = result.url; // èŽ·å–å›¾ç‰‡åœ°å€
            insertImgFn(url); // æ’入图片
          },
        },
        customMenus: {
          file: {
            tip: "上传文件",
            click: (editor) => {
              const input = document.createElement("input");
              input.type = "file";
              input.accept =
                "application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"; // æ”¯æŒçš„æ–‡ä»¶ç±»åž‹
              input.onchange = (e) => {
                const file = e.target.files[0];
                if (!file) return;
                const formData = new FormData();
                formData.append("file", file);
                // ç¡®ä¿ process.env.VUE_APP_BASE_API æ˜¯æ­£ç¡®çš„
                const uploadUrl =
                  process.env.VUE_APP_BASE_API + "/common/uploadSort";
                axios
                  .post(uploadUrl, formData, {
                    headers: {
                      Authorization: "Bearer " + getToken(),
                    },
                  })
                  .then((res) => {
                    const url = res.data.url; // èŽ·å–æ–‡ä»¶åœ°å€
                    // æ’入文件链接作为普通文本
                    editor.txt.append(url + " ");
                    // æˆ–者插入文件链接作为超链接
                    // editor.cmd.do('insertLink', { name: '文件链接', url: url });
                  })
                  .catch((err) => {
                    console.error("文件上传失败", err);
                  });
              };
              input.click();
            },
          },
        },
      },
      modes: "default", // or 'simple'
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/uploadSort",
      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: `<p>测试</p><video class="ql-video" controls="controls" controlslist="nofullscreen" type="video/mp4" style="object-fit:fill;width: 100%;" preload="auto" playsinline="true" x-webkit-airplay="allow" x5-video-orientation="portraint" x5-playsinline="true" x5-video-player-fullscreen="true" src="http://218.108.11.22:8093/profile-api/upload/vadio/营养泵操作规范.mp4"></video><video class="ql-video" controls="controls" controlslist="nofullscreen" type="video/mp4" style="object-fit:fill;width: 100%;" preload="auto" playsinline="true" x-webkit-airplay="allow" x5-video-orientation="portraint" x5-playsinline="true" x5-video-player-fullscreen="true" src="http://218.108.11.22:8093/profile-api/upload/vadio/注射器推注.mp4"></video><p>321</p>"`, //最终保存的内容
      fileName: "", //文件名
      dynamicTags: [],
      inputVisible: false,
      illnessVisible: 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: "", //填空题答案
      // æ€»æ¡æ•°
      total: 1,
      hetype: "",
      id: null,
      ruleForm: {
        campus: [],
        heLibraryTagList: [],
        tempDetpRelevances: [],
        version: "1.0.1",
      },
      rules: {},
      rulesa: {},
      mode: [],
      editableTabs: [],
      sortlist: [],
      usable: [],
      courtyardlist: [],
      precedencetype: [],
      optionsillness: [],
      illnesslistapi: [],
      illnesslist: [],
      options: [],
      optionstag: [],
      deptList: [],
      tempDetpRelevanceslist: [],
      props: { multiple: true, value: "deptId", label: "deptName" },
      // å†…网的部分(文件)
      oldPattern: "http://192.168.191.181:8095/profile/upload",
      // å†…网的部分(文件)
      oldPatternhtml: "/http:\/\/192\.168\.191\.181:8095\/profile\/upload\//g",
      // å¤–网部分(文件)
      newPattern: "http://218.108.11.22:8093/profile-api/upload",
      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();
    this.illnessUpdate();
    this.mode = store.getters.mode;
    this.editableTabs = store.getters.editableTabs;
    this.usable = store.getters.usable;
    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");
    },
  },
  beforeDestroy() {
    const editor = this.editor;
    if (editor == null) return;
    editor.destroy(); // ç»„件销毁时,及时销毁编辑器
  },
  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor); // ä¸€å®šè¦ç”¨ Object.seal(),否则会报错
    },
    // ---------------------------------
    processElement(element) {
      return { ...element, isoperation: null };
    },
    // èŽ·å–é¡µé¢æ•°æ®
    getList() {
      this.loading = true;
      this.id = this.$route.query.id;
      this.hetype = this.$route.query.hetype;
      if (this.id) {
        getlibraryinfo({ id: this.id }).then((res) => {
          this.ruleForm = res.data[0];
          if (this.ruleForm.campus)
            this.ruleForm.campus = this.ruleForm.campus.split(",");
          this.dynamicTags = res.data[0].heLibraryTagList.map(
            this.processElement
          );
          if (this.ruleForm.htmlRichText) {
            this.Getmissioncontent(this.ruleForm.htmlRichText);
          }
          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)
            : this.variablelist;
        });
      }
      // å®£æ•™åˆ†ç±»
      getheLibraryAssort({ hetype: 1 }).then((res) => {
        this.sortlist = res.rows;
        console.log(this.sortlist);
      });
      // éƒ¨é—¨
      listDept(this.queryParams).then((response) => {
        this.deptList = this.handleTree(response.data, "deptId");
      });
      // ------------------
      // let html =
      //   '<p>测试</p><video class="ql-video" controls="controls" controlslist="nofullscreen" type="video/mp4" style="object-fit:fill;width: 100%;" preload="auto" playsinline="true" x-webkit-airplay="allow" x5-video-orientation="portraint" x5-playsinline="true" x5-video-player-fullscreen="true" src="http://192.168.191.181:8095/profile/upload/vadio/营养泵介绍.mp4"></video><p>测试111</p><video class="ql-video" controls="controls" controlslist="nofullscreen" type="video/mp4" style="object-fit:fill;width: 100%;" preload="auto" playsinline="true" x-webkit-airplay="allow" x5-video-orientation="portraint" x5-playsinline="true" x5-video-player-fullscreen="true" src="http://192.168.191.181:8095/profile/upload/vadio/注射器推注.mp4"></video><p><br></p>';
      // // html = html.parserdom(this.oldPattern, this.newPattern);
      // html = this.parserdom(html);
      // console.log(html, "html");
      // this.loading = false;
    },
    // parser
    parserdom(html) {
      // åˆ›å»ºä¸€ä¸ªæ–°çš„DOM解析器
      var parser = new DOMParser();
      // å°†å­—符串解析为文档对象
      var doc = parser.parseFromString(html, "text/html");
      // å®šä¹‰è¦æ›¿æ¢çš„æ–°æ—§URL
      var oldUrlBase = "http://192.168.191.181:8095/profile/upload";
      var newUrlBase = "http://218.108.11.22:8093/profile-api/upload";
      // èŽ·å–æ‰€æœ‰çš„video元素
      var videos = doc.querySelectorAll("video");
      // éåŽ†æ‰€æœ‰çš„video元素并替换src属性
      videos.forEach(function (video) {
        var src = video.getAttribute("src");
        if (src.startsWith(oldUrlBase)) {
          video.setAttribute("src", src.replace(oldUrlBase, newUrlBase));
        }
      });
      // å°†ä¿®æ”¹åŽçš„æ–‡æ¡£è½¬æ¢å›žå­—符串
      var newContent = doc.body.innerHTML;
      return newContent;
    },
    submitForm(formName) {
      let tgs = [];
      this.dynamicTags.forEach((item) => {
        tgs.push(item.tagname);
      });
      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 = 1;
      console.log(22);
      this.ruleForm.suitway =
        this.ruleForm.suitway.length != 0
          ? this.ruleForm.suitway.join(",")
          : "";
      addrichText({
        content: this.parserdom(this.content),
        fileName: this.generateRandomHtmlFilename(),
      }).then((res) => {
        this.ruleForm.richText = res.msg;
        console.log(this.ruleForm.richText, "this.ruleForm.richText");
        // å¤„理内网html
        addrichText({
          content: this.content,
          fileName: this.generateRandomHtmlFilename(),
        }).then((resf) => {
          this.ruleForm.htmlRichText = resf.msg.replace(
            this.newPattern,
            this.oldPattern
          );
          console.log(this.ruleForm.htmlRichText, "this.ruleForm.htmlRichText");
          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) => {
              if (res.code == 200) {
                this.$modal.msgSuccess("新增成功");
                this.confirmillness(res.data);
                this.$router.go(-1);
              }
            });
          }
        });
      });
    },
    generateRandomHtmlFilename() {
      // ç”Ÿæˆä¸€ä¸ª0到1之间的随机数,并将其转换为字符串
      let randomNumber = Math.random().toString();
      // ç§»é™¤å‰é¢çš„0和小数点
      randomNumber = randomNumber.substring(6);
      // ç¡®ä¿ç”Ÿæˆçš„随机数是一定长度的,例如8位
      while (randomNumber.length < 8) {
        randomNumber = "0" + randomNumber;
      }
      // æ‹¼æŽ¥ä¸Š.html后缀
      return randomNumber + ".html";
    },
    // ä¿å­˜ç–¾ç—…
    confirmillness(guid) {
      this.illnesslist.forEach((item, index) => {
        if (guid) {
          item.outid = guid;
        } else {
          console.log(this.ruleForm);
          item.outid = this.ruleForm.id;
        }
        item.icd10name = item.icdname;
        item.icd10code = item.icdcode;
        item.type = 6;
        if (!item.id) {
          addtargetillness(item).then((res) => {});
        }
      });
      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() {
      this.$confirm("退出不会保留页面内容更改, æ˜¯å¦ç»§ç»­?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.$router.go(-1);
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消",
          });
        });
    },
    // ç§‘室处理
    Departmenttreatment() {
      this.ruleForm.deptNames = JSON.stringify(this.tempDetpRelevanceslist);
      const result = this.tempDetpRelevanceslist.map(
        (subArr) => subArr[subArr.length - 1]
      );
      // id数组查数组对象
      result.forEach((item) => {
        const condition = this.ruleForm.tempDetpRelevances.some(
          (obj) => obj.deptId === item
        );
        if (!condition) {
          listDept({ deptId: item }).then((res) => {
            console.log("dept");
            res.data[0].type = 2;
            this.ruleForm.tempDetpRelevances.push(res.data[0]);
          });
        }
      });
      // æ•°ç»„对象查id数组
      this.ruleForm.tempDetpRelevances.forEach((item) => {
        const condition = result.some((obj) => obj === item.deptId);
        if (!condition) {
          const index = this.ruleForm.tempDetpRelevances.indexOf(item);
          this.ruleForm.tempDetpRelevances[index].delFlag = 1;
        }
      });
      setTimeout(() => {
        this.submitForm();
      }, 1000);
      // this.submitForm();
    },
    // ä¿å­˜é¢˜ç›®ä¿¡æ¯
    Saveproblem() {},
    /** æŸ¥è¯¢é¢˜ç›®åˆ—表 */
    // æ–°å¢žå˜é‡
    addvariable() {
      this.variablelist.push({
        variatename: "",
        variate: "",
      });
    },
    // åˆ é™¤å˜é‡
    delvariable(item) {
      const index = this.variablelist.indexOf(item);
      if (index !== -1) {
        this.variablelist.splice(index, 1); // ä»Žç´¢å¼•位置删除一个元素
      } else {
        console.log("未找到该对象");
      }
    },
    // æŽ§åˆ¶æ–‡ä»¶
    handleChange(file, fileList) {
      this.fileList = fileList.slice(-3);
    },
    // æ ‡ç­¾-----------------
    gettabList() {
      const tagqueryParams = {
        pageNum: 1,
        pageSize: 1000,
        tagcategoryid: "0",
      };
      listtag(tagqueryParams).then((response) => {
        this.optionstag = response.rows;
      });
    },
    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;
    },
    handleInputConfirm() {
      let tagvalue = {};
      let tagname = this.inputValue;
      if (tagname) {
        listtag({
          pageNum: 1,
          pageSize: 1000,
          tagcategoryid: "0",
          tagname: tagname,
        }).then((res) => {
          if (res.rows[0]) {
            tagvalue = res.rows[0];
            tagvalue.isoperation = 1;
          } else {
            tagvalue = {
              tagname: tagname,
              isoperation: 1,
            };
          }
          this.ruleForm.heLibraryTagList.push(tagvalue);
          this.dynamicTags.push(tagvalue);
        });
      }
      this.inputVisible = false;
      this.inputValue = "";
    },
    remoteMethodtag(query) {
      if (query !== "") {
        this.loading = true;
        setTimeout(() => {
          this.loading = false;
          listtag({ tagname: query, tagcategoryid: "0" }).then((res) => {
            this.optionstag = res.rows;
          });
        }, 200);
      } else {
        this.optionstag = [];
      }
    },
    showInput() {
      this.inputVisible = true;
    },
    // ç–¾ç—…-----------------------
    illnessUpdate() {
      if (this.id) {
        getillness({ outid: this.$route.query.id, type: 6 }).then((res) => {
          this.illnesslist = res.rows;
          this.illnesslist.forEach((item) => {
            item.icdname = item.icd10name;
          });
        });
      }
    },
    // --------------------------
    // é¢„览模板
    PreviewTemplate() {
      this.drawer = true;
    },
    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("上传成功");
      //拼接出上传的图片在服务器的完整地址
      let imgUrl = res.url;
      console.log(res.url);
      imgUrl = imgUrl.replace(this.newPattern, this.oldPattern);
      console.log(imgUrl, "imgUrl");
      let type = imgUrl.substring(imgUrl.lastIndexOf(".") + 1);
      this.fileName = this.getFileNameFromPath(res.url);
      // èŽ·å–å¯Œæ–‡æœ¬ç»„ä»¶å®žä¾‹
      let quill = this.$refs.customQuillEditor.quill;
      // èŽ·å–å…‰æ ‡æ‰€åœ¨ä½ç½®
      let length = quill.getSelection().index;
      // æ’入图片||视频  res.info为服务器返回的图片地址
      if (type == "mp4" || type == "MP4" || type == "avi" || type == "AVI") {
        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);
    },
    // ä¸Šä¼ word成功
    uploadEditorSuccessword(res, file) {
      console.log("上传word文件成功");
      console.log(res, file, "word");
      let fileurl = res.url.replace(this.newPattern, this.oldPattern);
      axios
        .get(fileurl)
        .then((response) => {
          console.log(response.data, "数据"); // è¾“出获取到的文件内容
          this.$nextTick(() => {
            this.content = response.data;
          });
          this.fileName = this.getFileNameFromPath(response.url);
          console.log(this.fileName, "this.fileName");
        })
        .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(response.url);
          console.log(this.fileName, "this.fileName");
        })
        .catch((error) => {
          console.error("Failed to fetch file:", error);
        });
    },
    // å¤„理url
  },
};
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style src="@/assets/styles/global.css"></style>
<style lang="scss" scoped>
.sidecolumn {
  // width: 300px;
  // min-height: 100vh;
  // text-align: center;
  //   display: flex;
  //   margin-top: 20px;
  margin: 20px;
  margin-bottom: 0;
  padding: 20px;
  background: #edf1f7;
  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);
}
.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 {
    font-size: 24px;
    height: 30px;
    border-left: 3px solid #41a1be;
    padding-left: 3px;
    span {
      position: absolute;
      right: 80px;
    }
  }
  .demo-cascader {
    margin-right: 20px;
  }
  .PreviewTemplate {
    color: #02a7f0;
    cursor: pointer;
    font-size: 20px;
    margin: 0 20px;
  }
}
.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;
    line-height: 30px;
    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 {
  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 {
  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;
  }
}
</style>
src/views/knowledge/education/compilequer/index.vue
@@ -253,7 +253,7 @@
          </el-form-item>
        </el-form>
      </div>
      <!-- å®£æ•™å†…容 -->
    <!-- å®£æ•™å†…容 -->
      <div v-if="Editprogress == 2">
        <el-row :gutter="20">
          <el-col :span="4">
@@ -273,86 +273,27 @@
          </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"> -->
            <!-- </el-col>
            </el-row> -->
          </el-form>
        </div>
        <!-- <div>
          <div id="quillEditorQiniu">
            <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>
            <quill-editor
              class="editor"
              v-model="content"
              ref="customQuillEditor"
              :options="editorOption"
              @blur="onEditorBlur"
              @focus="onEditorFocus"
              @change="onEditorChange"
            >
            </quill-editor>
          </div>
        </div> -->
        <!-- æ–°ç»„ä»¶ -->
        <!-- WangEditor å¯Œæ–‡æœ¬ç¼–辑器 -->
        <div style="border: 1px solid #ccc; margin: 10px">
          <Toolbar
            style="border-bottom: 1px solid #ccc"
            :editor="editor"
            :editor="editorRef"
            :defaultConfig="toolbarConfig"
            :mode="modes"
            :mode="mode"
          />
          <Editor
            style="height: 500px; overflow-y: hidden"
            v-model="content"
            style="height: 800px; overflow-y: hidden"
            v-model:html="content"
            :defaultConfig="editorConfig"
            :mode="modes"
            @onCreated="onCreated"
            :mode="mode"
            @onCreated="handleEditorCreated"
          />
        </div>
        <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="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>
      </div>
@@ -369,201 +310,141 @@
</template>
<script>
import { quillEditor } from "vue-quill-editor";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import '@wangeditor/editor/dist/css/style.css';
import axios from "axios";
import { getToken } from "@/utils/auth";
import {
  getheLibraryAssort,
  delheLibraryAssort,
  addheLibraryAssort,
  addtargetillness,
  getlibrarylist,
  dellibraryinfo,
  deltargetillness,
  compilelibrary,
  addrichText,
  getlibraryinfo,
  getillnesslist,
  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: "aEducationinfo",
  components: { OptionalForm, Editor, Toolbar },
  data() {
    return {
      editor: null,
      content: "<p>hello</p>",
      toolbarConfig: {},
 // ç¼–辑器实例
      editorRef: null,
      // ç¼–辑器内容
      content: "<p>测试</p>",
      // ç¼–辑器模式
      mode: "default",
      // å·¥å…·æ é…ç½®
      toolbarConfig: {
        excludeKeys: [
          "group-video",
          "insertVideo",
          "uploadVideo",
          "emotion",
          "codeBlock",
        ]
      },
      // ç¼–辑器配置
      editorConfig: {
        placeholder: "请输入内容...",
        menus: [
          "head",
          "bold",
          "italic",
          "underline",
          "image",
          "link",
          "list",
          "undo",
          "redo",
          "file", // æ·»åŠ è‡ªå®šä¹‰æ–‡ä»¶ä¸Šä¼ èœå•
        ],
        uploadImgServer: process.env.VUE_APP_BASE_API + "/common/uploadSort", // å›¾ç‰‡ä¸Šä¼ æŽ¥å£
        uploadImgHeaders: {
          Authorization: "Bearer " + getToken(),
        }, // è‡ªå®šä¹‰ä¸Šä¼ çš„ headers
        uploadImgParams: { key: "value" }, // è‡ªå®šä¹‰ä¸Šä¼ çš„参数
        uploadImgMaxSize: 2 * 1024 * 1024, // å›¾ç‰‡æœ€å¤§å¤§å°ï¼Œå•位 Byte
        uploadImgMaxLength: 1, // ä¸€æ¬¡æœ€å¤šä¸Šä¼ å›¾ç‰‡æ•°é‡
        uploadImgTimeout: 3 * 60 * 1000, // è¶…时时间,单位 ms
        uploadImgHooks: {
          customInsert: (insertImgFn, result) => {
            const url = result.url; // èŽ·å–å›¾ç‰‡åœ°å€
            insertImgFn(url); // æ’入图片
          },
        },
        customMenus: {
          file: {
            tip: "上传文件",
            click: (editor) => {
              const input = document.createElement("input");
              input.type = "file";
              input.accept =
                "application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"; // æ”¯æŒçš„æ–‡ä»¶ç±»åž‹
              input.onchange = (e) => {
                const file = e.target.files[0];
                if (!file) return;
        placeholder: "请输入宣教内容...",
        MENU_CONF: {
          uploadImage: {
            server: process.env.VUE_APP_BASE_API + "/common/uploadSort",
            fieldName: "file",
            maxFileSize: 2 * 1024 * 1024,
            maxNumberOfFiles: 1,
            allowedFileTypes: ["image/*"],
            headers: {
              Authorization: "Bearer " + getToken()
            },
            customUpload: async (file, insertFn) => {
              try {
                const formData = new FormData();
                formData.append("file", file);
                // ç¡®ä¿ process.env.VUE_APP_BASE_API æ˜¯æ­£ç¡®çš„
                const uploadUrl =
                  process.env.VUE_APP_BASE_API + "/common/uploadSort";
                axios
                  .post(uploadUrl, formData, {
                const response = await axios.post(
                  process.env.VUE_APP_BASE_API + "/common/uploadSort",
                  formData,
                  {
                    headers: {
                      Authorization: "Bearer " + getToken(),
                    },
                  })
                  .then((res) => {
                    const url = res.data.url; // èŽ·å–æ–‡ä»¶åœ°å€
                    // æ’入文件链接作为普通文本
                    editor.txt.append(url + " ");
                    // æˆ–者插入文件链接作为超链接
                    // editor.cmd.do('insertLink', { name: '文件链接', url: url });
                  })
                  .catch((err) => {
                    console.error("文件上传失败", err);
                  });
              };
              input.click();
            },
          },
        },
                      "Content-Type": "multipart/form-data",
                      Authorization: "Bearer " + getToken()
                    }
                  }
                );
                if (response.data && response.data.url) {
                  let imgUrl = response.data.url;
                  imgUrl = imgUrl.replace(
                    "http://218.108.11.22:8093/profile-api/upload",
                    "http://192.168.191.181:8095/profile/upload"
                  );
                  insertFn(imgUrl);
                }
              } catch (error) {
                console.error("图片上传失败", error);
                this.$message.error("图片上传失败");
              }
            }
          }
        }
      },
      modes: "default", // or 'simple'
      // ä¸Šä¼ é…ç½®
      headers: {
        Authorization: "Bearer " + getToken(),
        Authorization: "Bearer " + getToken()
      },
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/uploadSort",
      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: `<p>测试</p><video class="ql-video" controls="controls" controlslist="nofullscreen" type="video/mp4" style="object-fit:fill;width: 100%;" preload="auto" playsinline="true" x-webkit-airplay="allow" x5-video-orientation="portraint" x5-playsinline="true" x5-video-player-fullscreen="true" src="http://218.108.11.22:8093/profile-api/upload/vadio/营养泵操作规范.mp4"></video><video class="ql-video" controls="controls" controlslist="nofullscreen" type="video/mp4" style="object-fit:fill;width: 100%;" preload="auto" playsinline="true" x-webkit-airplay="allow" x5-video-orientation="portraint" x5-playsinline="true" x5-video-player-fullscreen="true" src="http://218.108.11.22:8093/profile-api/upload/vadio/注射器推注.mp4"></video><p>321</p>"`, //最终保存的内容
      fileName: "", //文件名
      // é¡µé¢çŠ¶æ€
      Editprogress: 1,
      loading: false,
      // è¡¨å•数据
      ruleForm: {
        campus: [],
        heLibraryTagList: [],
        tempDetpRelevances: [],
        version: "1.0.1",
        preachname: "",
        preachcontent: "",
        isAvailable: "",
        suitway: []
      },
      // å…¶ä»–数据
      dynamicTags: [],
      sortlist: [],
      courtyardlist: [],
      illnesslist: [],
      deptList: [],
      tempDetpRelevanceslist: [],
      variablelist: [
        { variatename: "姓名", variate: "${name}", default: 1 },
        { variatename: "电话", variate: "${phone}", default: 1 },
        { variatename: "病情", variate: "${illness}", default: 1 }
      ],
      props: {
        multiple: true,
        value: "deptId",
        label: "deptName"
      },
      fileName: "", //文件名
      inputVisible: false,
      illnessVisible: 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: [], //多选题选中
@@ -572,28 +453,16 @@
      total: 1,
      hetype: "",
      id: null,
      ruleForm: {
        campus: [],
        heLibraryTagList: [],
        tempDetpRelevances: [],
        version: "1.0.1",
      },
      rules: {},
      rulesa: {},
      mode: [],
      editableTabs: [],
      sortlist: [],
      usable: [],
      courtyardlist: [],
      precedencetype: [],
      optionsillness: [],
      illnesslistapi: [],
      illnesslist: [],
      options: [],
      optionstag: [],
      deptList: [],
      tempDetpRelevanceslist: [],
      props: { multiple: true, value: "deptId", label: "deptName" },
      // å†…网的部分(文件)
      oldPattern: "http://192.168.191.181:8095/profile/upload",
      // å†…网的部分(文件)
@@ -624,11 +493,7 @@
      ],
      addvalue: "添加题目",
      variablelist: [
        { variatename: "姓名", variate: "${name}", default: 1 },
        { variatename: "电话", variate: "${phone}", default: 1 },
        { variatename: "病情", variate: "${illness}", default: 1 },
      ],
      // æŸ¥è¯¢å‚æ•°
      queryParams: {
        pageNum: 1,
@@ -655,11 +520,15 @@
    this.courtyardlist = store.getters.courtyardlist;
  },
  watch: {
    content(newVal, oldVal) {
      //this.$emit('input', newVal);
      console.log(newVal, "A");
      console.log(oldVal, "B");
    },
    // content(newVal, oldVal) {
    //   //this.$emit('input', newVal);
    //   console.log(newVal, "A");
    //   console.log(oldVal, "B");
    // },
    content(newVal) {
      // å†…容变化时触发,可以在这里处理自动保存等逻辑
      this.$emit('content-change', newVal)
    }
  },
  beforeDestroy() {
    const editor = this.editor;
@@ -670,7 +539,24 @@
    onCreated(editor) {
      this.editor = Object.seal(editor); // ä¸€å®šè¦ç”¨ Object.seal(),否则会报错
    },
    // ç¼–辑器创建回调
   handleEditorCreated(editor) {
      this.editorRef = editor;
      console.log("编辑器已创建", editor);
    },
   // é”€æ¯ç¼–辑器
    destroyEditor() {
      if (this.editorRef) {
        this.editorRef.destroy();
        this.editorRef = null;
      }
    },
    // èŽ·å–å†…å®¹HTML
    getEditorContent() {
      return this.content;
    },
    // ---------------------------------
    processElement(element) {
      return { ...element, isoperation: null };
@@ -1110,25 +996,40 @@
          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(response.url);
    //       console.log(this.fileName, "this.fileName");
    //     })
    //     .catch((error) => {
    //       console.error("Failed to fetch file:", error);
    //     });
    // },
    // èŽ·å–è¿œç¨‹å†…å®¹
    Getmissioncontent(url) {
      axios
        .get(url)
      axios.get(url)
        .then((response) => {
          console.log(response.data, "数据"); // è¾“出获取到的文件内容
          this.content = response.data;
          this.fileName = this.getFileNameFromPath(response.url);
          console.log(this.fileName, "this.fileName");
        })
        .catch((error) => {
          console.error("Failed to fetch file:", error);
          console.error("获取内容失败:", error);
        });
    },
    // å¤„理url
  },
  // ç”Ÿå‘½å‘¨æœŸé’©å­
  beforeUnmount() {
    this.destroyEditor()
  },
};
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style src="@/assets/styles/global.css"></style>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style lang="scss" scoped>
.sidecolumn {
  // width: 300px;
src/views/patient/propaganda/QuestionnaireTask.vue
@@ -80,6 +80,15 @@
                    >
                  </el-radio-group>
                </el-form-item>
                <!-- <el-form-item label="服务形式">
                  <SortCheckbox
                    v-model="checkList"
                    :options="checkboxlist"
                    value-key="value"
                    label-key="label"
                    @change="checkSelectionChange"
                  />
                </el-form-item> -->
                <el-form-item label="执行周期" prop="longTask">
                  <el-radio-group v-model="form.longTask">
                    <el-radio :label="0">自定义周期</el-radio>
@@ -916,6 +925,7 @@
} from "@/api/AiCentre/index";
import OptionalForm from "@/components/OptionalForm"; //疾病添加组件
import SFtable from "@/components/SFtable"; //表格组件
import SortCheckbox from "@/components/SortCheckbox"; //表格组件
import { MessageBox } from "element-ui";
export default {
@@ -1028,7 +1038,8 @@
        pageNum: 1, //
        pageSize: 10,
      },
      checkList: "",
      checkList: '',
      selectedOrder: [],
      deliverytopqueryParams: {
        pageNum: 1, //
        pageSize: 10,
@@ -1195,7 +1206,7 @@
      serviceType: null,
    };
  },
  components: { SFtable, OptionalForm },
  components: { SFtable, OptionalForm, SortCheckbox },
  created() {
    this.appraiselist = store.getters.appraiselist;
@@ -1568,6 +1579,11 @@
        }
      });
    },
    checkSelectionChange(selectedValues, selectedOrder) {
      this.selectedOrder = selectedOrder;
      console.log("当前选中:", selectedValues);
      console.log("选中顺序:", selectedOrder);
    },
    getillness(id) {
      if (id) {
        getillness({ outid: id, type: 5 }).then((res) => {