Browse Source

接入企业统计和修改职位添加界面

bobo 3 years ago
parent
commit
edb79b219a
10 changed files with 615 additions and 83 deletions
  1. 1 0
      package.json
  2. 301 0
      src/components/edit/index.vue
  3. 4 0
      src/components/jobs.scss
  4. 141 73
      src/components/jobs.vue
  5. 4 0
      src/main.js
  6. 14 0
      src/utils/api.js
  7. 16 0
      src/utils/request.js
  8. 17 6
      src/views/Home.vue
  9. 1 1
      src/views/login.vue
  10. 116 3
      yarn.lock

+ 1 - 0
package.json

@@ -12,6 +12,7 @@
     "core-js": "^3.6.5",
     "element-ui": "^2.15.6",
     "vue": "^2.6.11",
+    "vue-quill-editor": "^3.0.6",
     "vue-router": "^3.2.0",
     "vuex": "^3.4.0"
   },

+ 301 - 0
src/components/edit/index.vue

@@ -0,0 +1,301 @@
+<template>
+  <div :class="{notShow: showTool == 1, showT: showTool == 0 } ">
+    <el-upload
+        :action="uploadUrl"
+        :before-upload="handleBeforeUpload"
+        :on-success="handleUploadSuccess"
+        :on-error="handleUploadError"
+        name="file"
+        :show-file-list="false"
+        :headers="headers"
+        style="display: none"
+        ref="upload"
+        v-if="this.type == 'url'"
+    ></el-upload>
+
+    <div :class="{editor: true, notShow: showTool == 1, showTool: showTool == 1 } " ref="editor" :style="styles"></div>
+  </div>
+</template>
+
+<script>
+import Quill from "quill";
+import "quill/dist/quill.core.css";
+import "quill/dist/quill.snow.css";
+import "quill/dist/quill.bubble.css";
+import { getToken } from "@/utils/auth";
+
+export default {
+  name: "Editor",
+  props: {
+    /* 编辑器的内容 */
+    value: {
+      type: String,
+      default: "",
+    },
+    /* 高度 */
+    height: {
+      type: Number,
+      default: null,
+    },
+    /* 最小高度 */
+    minHeight: {
+      type: Number,
+      default: null,
+    },
+    /* 只读 */
+    readOnly: {
+      type: Boolean,
+      default: false,
+    },
+    // 上传文件大小限制(MB)
+    fileSize: {
+      type: Number,
+      default: 5,
+    },
+    /* 类型(base64格式、url格式) */
+    type: {
+      type: String,
+      default: "url",
+    },
+    /* */
+    showTool: {
+      type: Number,
+      default: 0,
+    }
+
+  },
+  data() {
+    return {
+      uploadUrl: process.env.VUE_APP_BASE_API + "/file/upload/single/qiniu", // 上传的图片服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken()
+      },
+      Quill: null,
+      currentValue: "",
+      options: {
+        theme: "snow",
+        bounds: document.body,
+        debug: "warn",
+        modules: {
+          // 工具栏配置
+          toolbar: [
+            ["bold", "italic", "underline", "strike"],       // 加粗 斜体 下划线 删除线
+            ["blockquote", "code-block"],                    // 引用  代码块
+            [{ list: "ordered" }, { list: "bullet" }],       // 有序、无序列表
+            [{ indent: "-1" }, { indent: "+1" }],            // 缩进
+            [{ size: ["small", false, "large", "huge"] }],   // 字体大小
+            [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 标题
+            [{ color: [] }, { background: [] }],             // 字体颜色、字体背景颜色
+            [{ align: [] }],                                 // 对齐方式
+            ["clean"],                                       // 清除文本格式
+            ["link", "image", "video"]                       // 链接、图片、视频
+          ]
+        },
+        placeholder: "请输入内容",
+        readOnly: this.readOnly,
+      },
+    };
+  },
+  computed: {
+    styles() {
+      let style = {};
+      if (this.minHeight) {
+        style.minHeight = `${this.minHeight}px`;
+      }
+      if (this.height) {
+        style.height = `${this.height}px`;
+      }
+      return style;
+    },
+  },
+  watch: {
+    value: {
+      handler(val) {
+        if (val !== this.currentValue) {
+          this.currentValue = val === null ? "" : val;
+          if (this.Quill) {
+            this.Quill.pasteHTML(this.currentValue);
+          }
+        }
+      },
+      immediate: true,
+    }
+  },
+  mounted() {
+    this.init();
+  },
+  beforeDestroy() {
+    this.Quill = null;
+  },
+  methods: {
+    init() {
+      const editor = this.$refs.editor;
+      this.Quill = new Quill(editor, this.options);
+
+      // 如果设置了上传地址则自定义图片上传事件
+      if (this.type == 'url') {
+        let toolbar = this.Quill.getModule("toolbar");
+        toolbar.addHandler("image", (value) => {
+          this.uploadType = "image";
+          if (value) {
+            this.$refs.upload.$children[0].$refs.input.click();
+          } else {
+            this.quill.format("image", false);
+          }
+        });
+      }
+      this.Quill.pasteHTML(this.currentValue);
+      this.Quill.on("text-change", (delta, oldDelta, source) => {
+        const html = this.$refs.editor.children[0].innerHTML;
+        const text = this.Quill.getText();
+        const quill = this.Quill;
+        const currentHtml = (('<p><br></p>' == html) ? undefined : html);
+        this.currentValue = currentHtml;
+        this.$emit("input", currentHtml);
+        this.$emit("on-change", { html: currentHtml, text, quill });
+      });
+      this.Quill.on("text-change", (delta, oldDelta, source) => {
+        this.$emit("on-text-change", delta, oldDelta, source);
+      });
+      this.Quill.on("selection-change", (range, oldRange, source) => {
+        this.$emit("on-selection-change", range, oldRange, source);
+      });
+      this.Quill.on("editor-change", (eventName, ...args) => {
+        this.$emit("on-editor-change", eventName, ...args);
+      });
+    },
+    //处理是否显示toobar
+    showToolBar(){
+
+    },
+
+    // 上传前校检格式和大小
+    handleBeforeUpload(file) {
+      // 校检文件大小
+      if (this.fileSize) {
+        const isLt = file.size / 1024 / 1024 < this.fileSize;
+        if (!isLt) {
+          this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
+          return false;
+        }
+      }
+      return true;
+    },
+    handleUploadSuccess(res, file) {
+      // 获取富文本组件实例
+      let quill = this.Quill;
+      // 如果上传成功
+      if (res.code == 200) {
+        // 获取光标所在位置
+        let length = quill.getSelection().index;
+        // 插入图片  res.url为服务器返回的图片地址
+        quill.insertEmbed(length, "image", res?.data?.url);
+        // 调整光标到最后
+        quill.setSelection(length + 1);
+      } else {
+        this.$message.error("图片插入失败");
+      }
+    },
+    handleUploadError() {
+      this.$message.error("图片插入失败");
+    }
+  },
+};
+</script>
+
+<style>
+
+
+
+.notShow .editor{
+  border: 1px solid rgb(220,223,230)!important;
+}
+.editor,
+.ql-toolbar {
+  white-space: pre-wrap !important;
+  line-height: normal !important;
+}
+.notShow .ql-toolbar{
+  display: none;
+}
+
+.showT .ql-toolbar{
+  display: block;
+}
+.quill-img {
+  display: none;
+}
+.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>

+ 4 - 0
src/components/jobs.scss

@@ -36,6 +36,10 @@
       cursor: pointer;
     }
   }
+  add-job-div{
+    width: 80%;
+    height: 70%;
+  }
   .job-type {
     overflow: hidden;
     background: #f7f7f7;

+ 141 - 73
src/components/jobs.vue

@@ -34,89 +34,114 @@
         </div>
       </div>
     </section>
-    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="30%">
-      <el-form
-        ref="form"
-        :model="form"
-        :rules="rules"
-        :close-on-click-modal="false"
-      >
-        <el-form-item
-          label="职位名称"
-          prop="postName"
-          :label-width="formLabelWidth"
-        >
-          <el-input v-model="form.postName" autocomplete="off"></el-input>
-        </el-form-item>
-        <el-form-item
-          label="工作经历(年)"
-          prop="workYear"
-          :label-width="formLabelWidth"
-        >
-          <el-input v-model="form.workYear" autocomplete="off"></el-input>
-        </el-form-item>
-        <el-form-item
-          label="最低学历"
-          prop="educationBg"
-          :label-width="formLabelWidth"
-        >
-          <el-select v-model="form.educationBg" placeholder="请选面试结果">
-            <el-option label="未参加面试" value="shanghai"></el-option>
-            <el-option label="未通过" value="beijing"></el-option>
-            <el-option label="通过" value="beijing"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item
-          label="职位描述"
-          prop="description"
-          :label-width="formLabelWidth"
+
+    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%">
+      <div class="add-job-div">
+        <el-form
+          ref="form"
+          :model="form"
+          :rules="rules"
+          :close-on-click-modal="false"
         >
-          <el-input
-            type="textarea"
-            :rows="2"
-            placeholder="请输入内容"
-            v-model="form.description"
+          <el-form-item
+            label="职位名称"
+            prop="postName"
+            :label-width="formLabelWidth"
+
           >
-          </el-input>
-        </el-form-item>
-        <!-- <el-form-item label="工资待遇" :label-width="formLabelWidth">
-          <el-input v-model="form.name" autocomplete="off"></el-input>
-        </el-form-item> -->
-        <el-form-item
-          label="最低工资"
-          prop="lowestSalary"
-          :label-width="formLabelWidth"
-        >
-          <el-input v-model="form.lowestSalary" autocomplete="off"></el-input>
-        </el-form-item>
-        <el-form-item
-          label="工资待遇"
-          prop="highestSalary"
-          :label-width="formLabelWidth"
-        >
-          <el-input v-model="form.highestSalary" autocomplete="off"></el-input>
-        </el-form-item>
-        <el-form-item
-          label="工作地点"
-          prop="workPlace"
-          :label-width="formLabelWidth"
-        >
-          <el-input v-model="form.workPlace" autocomplete="off"></el-input>
-        </el-form-item>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button @click="cancel">取 消</el-button>
-        <el-button type="primary" @click="submit">确 定</el-button>
+            <el-input v-model="form.postName" placeholder="请录入职位名称" autocomplete="off"></el-input>
+          </el-form-item>
+          <el-form-item
+            label="工作经历(年)"
+            prop="workYear"
+            :label-width="formLabelWidth"
+          >
+            <el-input v-model="form.workYear" placeholder="请录入工作经验限制,输入0则为不限"  autocomplete="off"></el-input>
+          </el-form-item>
+          <el-form-item
+            label="最低学历"
+            prop="educationBg"
+            :label-width="formLabelWidth"
+          >
+            <el-select v-model="form.educationBg" placeholder="请选择">
+
+              <el-option v-for=" (item) in jobForm.educations" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            label="职位描述"
+            prop="description"
+            :label-width="formLabelWidth"
+          >
+            <el-col :span="24">
+              <text-edit
+                  :minHeight="jobForm.description.minHeight"
+                  :show-tool="1"
+              ></text-edit>
+            </el-col>
+          </el-form-item>
+          <!-- <el-form-item label="工资待遇" :label-width="formLabelWidth">
+            <el-input v-model="form.name" autocomplete="off"></el-input>
+          </el-form-item> -->
+          <el-form-item
+            label="最低工资"
+            prop="lowestSalary"
+            :label-width="formLabelWidth"
+          >
+            <el-col :span="10">
+              <el-select v-model="form.lowestSalary" placeholder="请选择">
+                <el-option
+                    v-for="item of 50"
+                    :disabled="item >= form.highestSalary "
+                    :key="item"
+                    :label="item"
+                    :value="item">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="2">
+              <div :style="{width:'100%',fontSize:'50px'}">~</div>
+            </el-col>
+            <el-col :span="10">
+              <el-select v-model="form.highestSalary" placeholder="请选择">
+                <el-option
+                    v-for="item of 50"
+                    :disabled="item <= form.lowestSalary "
+                    :key="item"
+                    :label="item"
+                    :value="item">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="2">
+              <div :style="{width:'100%',fontSize:'40px',paddingLeft: '3px',fontWeight: 1 }">K</div>
+            </el-col>
+          </el-form-item>
+          <el-form-item
+            label="工作地点"
+            prop="workPlace"
+            :label-width="formLabelWidth"
+          >
+            <el-input v-model="form.workPlace" autocomplete="off"></el-input>
+          </el-form-item>
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button @click="cancel">取 消</el-button>
+          <el-button type="primary" @click="submit">确 定</el-button>
+        </div>
       </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-import { addcomPost, getComPostList, updateComPost } from "@/utils/api";
+import { addcomPost, getComPostList, updateComPost,getDicData } from "@/utils/api";
+import textEdit from './edit/index'
 export default {
   name: "",
-  components: {},
+  components: {
+    textEdit,
+  },
   data() {
     return {
       queryParams: {
@@ -124,6 +149,12 @@ export default {
         pageSize: 10,
         postName: "",
       },
+      jobForm:{
+        educations:[],
+        description: {
+          minHeight: 150
+        }
+      },
       jobList: [],
       dialogTitle: "",
       dialogVisible: false,
@@ -156,8 +187,19 @@ export default {
   },
   created() {
     this.handlegetComPostList();
+    this.getDicData();
   },
   methods: {
+
+    getDicData(){
+      let eduDictType = 'degr_educ';
+      getDicData(eduDictType)
+        .then((res) => {
+          this.jobForm.educations = res.data;
+
+        })
+
+    },
     goDetails(id) {
       this.$router.push({ path: "/jobdetails", query: { id: id } });
     },
@@ -238,4 +280,30 @@ export default {
 <style lang='scss' scoped>
 //@import url()
 @import "./jobs.scss";
+.add-job-div{
+  width: 76%;
+  height: 70%;
+  margin: auto;
+  .dialog-footer{
+    width: 180px;
+    margin: auto;
+  }
+}
+::v-deep{
+  .el-dialog{
+    -moz-box-shadow: rgba(169, 169, 169, 0.6) 0px 0px 0px 20px; /* 老的 Firefox */
+    box-shadow: rgba(169, 169, 169, 0.6) 0px 0px 0px 20px;
+    border-radius: 0px;
+    .el-dialog__header{
+      background: rgb(0,179,138);
+      span{
+        color: white;
+        font-size: 16px;
+      };
+      .el-dialog__headerbtn .el-dialog__close{
+        color: white;
+      }
+    }
+  }
+}
 </style>

+ 4 - 0
src/main.js

@@ -5,6 +5,8 @@ import router from './router'
 
 import ElementUI from 'element-ui';
 import 'element-ui/lib/theme-chalk/index.css';
+// import { quillEditor } from 'vue-quill-editor'
+// Vue.use(quillEditor);
 Vue.use(ElementUI);
 
 // Vue.prototype.baseApiUrl = process.env.VUE_APP_BASE_API;
@@ -12,6 +14,8 @@ Vue.use(ElementUI);
 // 引入全局样式文件
 import '@/assets/scss/index.scss'
 
+
+
 Vue.config.productionTip = false
 
 // 引入uView提供的对vuex的简写法文件

+ 14 - 0
src/utils/api.js

@@ -7,6 +7,20 @@ export function getCompanyInfo() {
     method: 'get'
   })
 }
+// 获取企业统计信息
+export function getCompanyTotalInfo() {
+  return request({
+    url: '/comPost/com/total',
+    method: 'get',
+  })
+}
+// 获取字典数据 data字典类型
+export function getDicData(data) {
+  return request({
+    url: '/dict/data/type/'+data,
+    method: 'get',
+  })
+}
 
 // 企业编辑
 export function editCompany(data) {

+ 16 - 0
src/utils/request.js

@@ -17,6 +17,7 @@ const service = axios.create({
 let token = getToken();
 console.log('token', token);
 service.interceptors.request.use(config => {
+
   if (token) {
     config.headers['Authorization'] = 'Bearer ' + token // 让每个请求携带自定义token 请根据实际情况自行修改
     // config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
@@ -59,6 +60,21 @@ service.interceptors.response.use(
           //   location.reload()// 为了重新实例化vue-router对象 避免bug
           // })
         })
+      }else if (res.code === 400) {
+        MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
+          confirmButtonText: '重新登录',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          console.log('location', location);
+          localStorage.setItem('fromUrl', location.hash);
+          location.href = '/#/login';
+          localStorage.setItem("lifeData", JSON.stringify({}));
+          // location.reload()
+          // store.dispatch('FedLogOut').then(() => {
+          //   location.reload()// 为了重新实例化vue-router对象 避免bug
+          // })
+        })
       }
       return Promise.reject('error')
     } else {

+ 17 - 6
src/views/Home.vue

@@ -15,7 +15,7 @@
             <div class="left">
               <div class="data-cell">
                 <div class="up">
-                  <span>{{ companyInfo.zpzwTotal || 0 }}</span
+                  <span>{{ companyTotal.recruitWorkNum || 0 }}</span
                   >个
                 </div>
                 <div class="down">
@@ -32,7 +32,7 @@
               </div>
               <div class="data-cell">
                 <div class="up">
-                  <span>{{ companyInfo.ypzwTotal || 0 }}</span
+                  <span>{{ companyTotal.viewNum || 0 }}</span
                   >个
                 </div>
                 <div class="down">
@@ -49,7 +49,7 @@
               </div>
               <div class="data-cell">
                 <div class="up">
-                  <span>{{ companyInfo.jlTotal || 0 }}</span
+                  <span>{{ companyTotal.receivedResumeNum || 0 }}</span
                   >个
                 </div>
                 <div class="down">
@@ -94,10 +94,10 @@
         >
           <el-menu-item index="1">公司主页</el-menu-item>
           <el-menu-item index="2"
-            >招聘职位({{ companyInfo.zpzwTotal || 0 }})</el-menu-item
+            >招聘职位({{ companyTotal.recruitWorkNum || 0 }})</el-menu-item
           >
           <el-menu-item index="3"
-            >应聘信息({{ companyInfo.ypzwTotal || 0 }})</el-menu-item
+            >应聘信息({{ companyTotal.receivedResumeNum || 0 }})</el-menu-item
           >
         </el-menu>
       </div>
@@ -178,7 +178,7 @@ import Mainmenu from "@/components/mainmenu.vue";
 import Jobs from "@/components/jobs.vue";
 import Applys from "@/components/applys.vue";
 
-import { getCompanyInfo, getTrade, getScope } from "@/utils/api";
+import { getCompanyInfo, getTrade, getScope,getCompanyTotalInfo } from "@/utils/api";
 
 export default {
   name: "Home",
@@ -194,6 +194,7 @@ export default {
       activeName: "second",
       companymenuIndex: "1",
       companyInfo: {},
+      companyTotal:{},
       trade: [],
       scope: [],
     };
@@ -231,6 +232,7 @@ export default {
     this.getinfo();
     this.handelGetTrade();
     this.handelGetScope();
+    this.getCompanyInfo();
   },
   methods: {
     companymenuSelect(key) {
@@ -246,6 +248,15 @@ export default {
           console.log("fetchList err", err);
         });
     },
+    getCompanyInfo() {
+      getCompanyTotalInfo()
+        .then((res) => {
+          this.companyTotal = res.data;
+        })
+        .catch((err) => {
+
+        });
+    },
     handelGetTrade() {
       let that = this;
       getTrade()

+ 1 - 1
src/views/login.vue

@@ -51,7 +51,7 @@
               <i class="el-icon-edit"></i>
             </span>
           </el-form-item>
-          <el-form-item style="" prop="code">
+          <el-form-item style="display: flex;flex-wrap: nowrap;flex-direction:column;flejustify-content: space-between" prop="code">
             <span class="svg-container svg-container-admin">
               <i class="el-icon-s-help"></i>
             </span>

+ 116 - 3
yarn.lock

@@ -1829,6 +1829,13 @@ async-limiter@~1.0.0:
   resolved "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
   integrity sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=
 
+async-validator@~1.8.1:
+  version "1.8.5"
+  resolved "https://registry.npmmirror.com/async-validator/download/async-validator-1.8.5.tgz?cache=0&sync_timestamp=1634529574100&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fasync-validator%2Fdownload%2Fasync-validator-1.8.5.tgz#dc3e08ec1fd0dddb67e60842f02c0cd1cec6d7f0"
+  integrity sha1-3D4I7B/Q3dtn5ghC8CwM0c7G1/A=
+  dependencies:
+    babel-runtime "6.x"
+
 async@^2.6.2:
   version "2.6.3"
   resolved "https://registry.nlark.com/async/download/async-2.6.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fasync%2Fdownload%2Fasync-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
@@ -1869,6 +1876,13 @@ aws4@^1.8.0:
   resolved "https://registry.npm.taobao.org/aws4/download/aws4-1.11.0.tgz?cache=0&sync_timestamp=1604101166484&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
   integrity sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=
 
+axios@^0.24.0:
+  version "0.24.0"
+  resolved "https://registry.npmmirror.com/axios/download/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
+  integrity sha1-gE5voeS5xSiFAd2d/1anoJQNINY=
+  dependencies:
+    follow-redirects "^1.14.4"
+
 babel-eslint@^10.1.0:
   version "10.1.0"
   resolved "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232"
@@ -1881,6 +1895,11 @@ babel-eslint@^10.1.0:
     eslint-visitor-keys "^1.0.0"
     resolve "^1.12.0"
 
+babel-helper-vue-jsx-merge-props@^2.0.0:
+  version "2.0.3"
+  resolved "https://registry.npm.taobao.org/babel-helper-vue-jsx-merge-props/download/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6"
+  integrity sha1-Iq69OzOQIyjlEyk6jkmSs4T58bY=
+
 babel-loader@^8.1.0:
   version "8.2.3"
   resolved "https://registry.npmmirror.com/babel-loader/download/babel-loader-8.2.3.tgz?cache=0&sync_timestamp=1634769533620&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d"
@@ -1922,6 +1941,14 @@ babel-plugin-polyfill-regenerator@^0.2.2:
   dependencies:
     "@babel/helper-define-polyfill-provider" "^0.2.2"
 
+babel-runtime@6.x:
+  version "6.26.0"
+  resolved "https://registry.npm.taobao.org/babel-runtime/download/babel-runtime-6.26.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-runtime%2Fdownload%2Fbabel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
+  integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
+  dependencies:
+    core-js "^2.4.0"
+    regenerator-runtime "^0.11.0"
+
 balanced-match@^1.0.0:
   version "1.0.2"
   resolved "https://registry.nlark.com/balanced-match/download/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -2540,6 +2567,11 @@ clone@^1.0.2:
   resolved "https://registry.nlark.com/clone/download/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
   integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
 
+clone@^2.1.1:
+  version "2.1.2"
+  resolved "https://registry.nlark.com/clone/download/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
+  integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
+
 coa@^2.0.2:
   version "2.0.2"
   resolved "https://registry.npm.taobao.org/coa/download/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
@@ -2768,6 +2800,11 @@ core-js-compat@^3.16.0, core-js-compat@^3.16.2, core-js-compat@^3.6.5:
     browserslist "^4.17.5"
     semver "7.0.0"
 
+core-js@^2.4.0:
+  version "2.6.12"
+  resolved "https://registry.npmmirror.com/core-js/download/core-js-2.6.12.tgz?cache=0&sync_timestamp=1635142905717&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcore-js%2Fdownload%2Fcore-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
+  integrity sha1-2TM9+nsGXjR8xWgiGdb2kIWcwuw=
+
 core-js@^3.6.5:
   version "3.19.0"
   resolved "https://registry.npmmirror.com/core-js/download/core-js-3.19.0.tgz?cache=0&sync_timestamp=1635142905717&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcore-js%2Fdownload%2Fcore-js-3.19.0.tgz#9e40098a9bc326c7e81b486abbd5e12b9d275176"
@@ -3114,7 +3151,7 @@ deep-is@~0.1.3:
   resolved "https://registry.nlark.com/deep-is/download/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
   integrity sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=
 
-deepmerge@^1.5.2:
+deepmerge@^1.2.0, deepmerge@^1.5.2:
   version "1.5.2"
   resolved "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753"
   integrity sha1-EEmdhohEza1P7ghC34x/bwyVp1M=
@@ -3382,6 +3419,18 @@ electron-to-chromium@^1.3.878:
   resolved "https://registry.npmmirror.com/electron-to-chromium/download/electron-to-chromium-1.3.878.tgz?cache=0&sync_timestamp=1635094527403&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.878.tgz#baa9fb5c24b9b580f08fb245cbb52a22f8fc8fa8"
   integrity sha1-uqn7XCS5tYDwj7JFy7UqIvj8j6g=
 
+element-ui@^2.15.6:
+  version "2.15.6"
+  resolved "https://registry.nlark.com/element-ui/download/element-ui-2.15.6.tgz#c9609add35af5a686a4b7685dc1d757c75e01df3"
+  integrity sha1-yWCa3TWvWmhqS3aF3B11fHXgHfM=
+  dependencies:
+    async-validator "~1.8.1"
+    babel-helper-vue-jsx-merge-props "^2.0.0"
+    deepmerge "^1.2.0"
+    normalize-wheel "^1.0.1"
+    resize-observer-polyfill "^1.5.0"
+    throttle-debounce "^1.0.1"
+
 elliptic@^6.5.3:
   version "6.5.4"
   resolved "https://registry.npm.taobao.org/elliptic/download/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
@@ -3656,6 +3705,11 @@ event-pubsub@4.3.0:
   resolved "https://registry.nlark.com/event-pubsub/download/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e"
   integrity sha1-9o2Ba8KfHsAsU53FjI3UDOcss24=
 
+eventemitter3@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-2.0.3.tgz?cache=0&sync_timestamp=1598517714257&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventemitter3%2Fdownload%2Feventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
+  integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=
+
 eventemitter3@^4.0.0:
   version "4.0.7"
   resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.7.tgz?cache=0&sync_timestamp=1598517714257&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventemitter3%2Fdownload%2Feventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
@@ -3787,7 +3841,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
     assign-symbols "^1.0.0"
     is-extendable "^1.0.1"
 
-extend@~3.0.2:
+extend@^3.0.2, extend@~3.0.2:
   version "3.0.2"
   resolved "https://registry.nlark.com/extend/download/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
   integrity sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=
@@ -3830,6 +3884,11 @@ fast-deep-equal@^3.1.1:
   resolved "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
   integrity sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=
 
+fast-diff@1.1.2:
+  version "1.1.2"
+  resolved "https://registry.npm.taobao.org/fast-diff/download/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154"
+  integrity sha1-S2LEK44D3j+EhGC2OQeZIGldAVQ=
+
 fast-glob@^2.2.6:
   version "2.2.7"
   resolved "https://registry.nlark.com/fast-glob/download/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d"
@@ -3998,7 +4057,7 @@ flush-write-stream@^1.0.0:
     inherits "^2.0.3"
     readable-stream "^2.3.6"
 
-follow-redirects@^1.0.0:
+follow-redirects@^1.0.0, follow-redirects@^1.14.4:
   version "1.14.4"
   resolved "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
   integrity sha1-g4/fSKi73XnlLuUfsclOPtmLk3k=
@@ -5999,6 +6058,11 @@ normalize-url@^3.0.0:
   resolved "https://registry.nlark.com/normalize-url/download/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559"
   integrity sha1-suHE3E98bVd0PfczpPWXjRhlBVk=
 
+normalize-wheel@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npm.taobao.org/normalize-wheel/download/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45"
+  integrity sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=
+
 npm-run-path@^2.0.0:
   version "2.0.2"
   resolved "https://registry.npmmirror.com/npm-run-path/download/npm-run-path-2.0.2.tgz?cache=0&sync_timestamp=1633420549182&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@@ -6311,6 +6375,11 @@ param-case@2.1.x:
   dependencies:
     no-case "^2.2.0"
 
+parchment@^1.1.4:
+  version "1.1.4"
+  resolved "https://registry.npm.taobao.org/parchment/download/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5"
+  integrity sha1-rt7Xq5OP6SHUw0vDOc4RaLwv/eU=
+
 parent-module@^1.0.0:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/parent-module/download/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@@ -7042,6 +7111,27 @@ querystringify@^2.1.1:
   resolved "https://registry.npm.taobao.org/querystringify/download/querystringify-2.2.0.tgz?cache=0&sync_timestamp=1597686864502&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fquerystringify%2Fdownload%2Fquerystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
   integrity sha1-M0WUG0FTy50ILY7uTNogFqmu9/Y=
 
+quill-delta@^3.6.2:
+  version "3.6.3"
+  resolved "https://registry.npm.taobao.org/quill-delta/download/quill-delta-3.6.3.tgz#b19fd2b89412301c60e1ff213d8d860eac0f1032"
+  integrity sha1-sZ/SuJQSMBxg4f8hPY2GDqwPEDI=
+  dependencies:
+    deep-equal "^1.0.1"
+    extend "^3.0.2"
+    fast-diff "1.1.2"
+
+quill@^1.3.4:
+  version "1.3.7"
+  resolved "https://registry.npm.taobao.org/quill/download/quill-1.3.7.tgz#da5b2f3a2c470e932340cdbf3668c9f21f9286e8"
+  integrity sha1-2lsvOixHDpMjQM2/NmjJ8h+Shug=
+  dependencies:
+    clone "^2.1.1"
+    deep-equal "^1.0.1"
+    eventemitter3 "^2.0.3"
+    extend "^3.0.2"
+    parchment "^1.1.4"
+    quill-delta "^3.6.2"
+
 randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
   version "2.1.0"
   resolved "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@@ -7157,6 +7247,11 @@ regenerate@^1.4.2:
   resolved "https://registry.npm.taobao.org/regenerate/download/regenerate-1.4.2.tgz?cache=0&sync_timestamp=1604218353677&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerate%2Fdownload%2Fregenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
   integrity sha1-uTRtiCfo9aMve6KWN9OYtpAUhIo=
 
+regenerator-runtime@^0.11.0:
+  version "0.11.1"
+  resolved "https://registry.nlark.com/regenerator-runtime/download/regenerator-runtime-0.11.1.tgz?cache=0&sync_timestamp=1626993001371&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+  integrity sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk=
+
 regenerator-runtime@^0.13.4:
   version "0.13.9"
   resolved "https://registry.nlark.com/regenerator-runtime/download/regenerator-runtime-0.13.9.tgz?cache=0&sync_timestamp=1626993001371&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
@@ -7293,6 +7388,11 @@ requires-port@^1.0.0:
   resolved "https://registry.npm.taobao.org/requires-port/download/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
   integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
 
+resize-observer-polyfill@^1.5.0:
+  version "1.5.1"
+  resolved "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
+  integrity sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ=
+
 resolve-cwd@^2.0.0:
   version "2.0.0"
   resolved "https://registry.nlark.com/resolve-cwd/download/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
@@ -8197,6 +8297,11 @@ thread-loader@^2.1.3:
     loader-utils "^1.1.0"
     neo-async "^2.6.0"
 
+throttle-debounce@^1.0.1:
+  version "1.1.0"
+  resolved "https://registry.nlark.com/throttle-debounce/download/throttle-debounce-1.1.0.tgz#51853da37be68a155cb6e827b3514a3c422e89cd"
+  integrity sha1-UYU9o3vmihVctugns1FKPEIuic0=
+
 through2@^2.0.0:
   version "2.0.5"
   resolved "https://registry.npm.taobao.org/through2/download/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
@@ -8650,6 +8755,14 @@ vue-loader@^15.9.2:
     vue-hot-reload-api "^2.3.0"
     vue-style-loader "^4.1.0"
 
+vue-quill-editor@^3.0.6:
+  version "3.0.6"
+  resolved "https://registry.nlark.com/vue-quill-editor/download/vue-quill-editor-3.0.6.tgz#1f85646211d68a31a80a72cb7f45bb2f119bc8fb"
+  integrity sha1-H4VkYhHWijGoCnLLf0W7LxGbyPs=
+  dependencies:
+    object-assign "^4.1.1"
+    quill "^1.3.4"
+
 vue-router@^3.2.0:
   version "3.5.2"
   resolved "https://registry.npmmirror.com/vue-router/download/vue-router-3.5.2.tgz?cache=0&sync_timestamp=1634663514839&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fvue-router%2Fdownload%2Fvue-router-3.5.2.tgz#5f55e3f251970e36c3e8d88a7cd2d67a350ade5c"