heimawl
2023-06-29 958f682227fd2aae9efd5791c89fa3ef0f4cdc4c
备注信息
已添加12个文件
已修改6个文件
4552 ■■■■■ 文件已修改
package.json 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 166 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/education/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/questionbank/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/knowledge/questionnaire/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/repositoryai/matching/index.vue 752 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/repositoryai/matching/myAudio.vue 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/repositoryai/verbaltrick/particulars/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/communication/database/contacts.js 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/communication/database/emoji.js 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/communication/database/messages.js 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/communication/database/user.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/communication/index.vue 908 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/communication/lemon-message-voice.vue 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/healthinformation/index.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/messagebank/index.vue 932 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/shortmessage/taglibrary/index.vue 711 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/websocket/websocket.js 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -52,13 +52,17 @@
    "js-beautify": "1.13.0",
    "js-cookie": "3.0.1",
    "jsencrypt": "3.0.0-rc.1",
    "lemon-imui": "^1.7.7",
    "nprogress": "0.2.0",
    "quill": "1.3.7",
    "quill-image-drop-module": "^1.0.3",
    "quill-image-resize": "^3.0.9",
    "quill-image-resize-module": "^3.0.0",
    "sass": "^1.63.6",
    "screenfull": "5.0.2",
    "sortablejs": "1.10.2",
    "style-loader": "^3.3.3",
    "stylus-loader": "^7.1.3",
    "vue": "2.6.12",
    "vue-cli": "^2.9.6",
    "vue-codemirror": "^4.0.6",
@@ -83,11 +87,12 @@
    "eslint": "7.15.0",
    "eslint-plugin-vue": "7.2.0",
    "lint-staged": "10.5.3",
    "node-sass": "^8.0.0",
    "runjs": "4.4.2",
    "sass": "1.32.13",
    "sass-loader": "10.1.1",
    "sass-loader": "^10.4.1",
    "script-ext-html-webpack-plugin": "2.1.5",
    "script-loader": "^0.7.2",
    "stylus": "^0.59.0",
    "svg-sprite-loader": "5.1.1",
    "vue-template-compiler": "2.6.12"
  },
src/main.js
@@ -1,27 +1,27 @@
import Vue from 'vue'
import Vue from "vue";
import Cookies from 'js-cookie'
import Cookies from "js-cookie";
import * as echarts from "echarts";
import Element from 'element-ui'
import './assets/styles/element-variables.scss'
import Element from "element-ui";
import "./assets/styles/element-variables.scss";
import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'
import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
 //引入quill-editor编辑器
 import VueQuillEditor from 'vue-quill-editor'
 // require styles å¼•入样式
 import 'quill/dist/quill.core.css'
 import 'quill/dist/quill.snow.css'
 import 'quill/dist/quill.bubble.css'
 Vue.use(VueQuillEditor);
 // å¼•å…¥
import "@/assets/styles/index.scss"; // global css
import "@/assets/styles/ruoyi.scss"; // ruoyi css
import App from "./App";
import store from "./store";
import router from "./router";
import directive from "./directive"; // directive
import plugins from "./plugins"; // plugins
import { download } from "@/utils/request";
//引入quill-editor编辑器
import VueQuillEditor from "vue-quill-editor";
// require styles å¼•入样式
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
Vue.use(VueQuillEditor);
// å¼•å…¥
import { codemirror } from "vue-codemirror";
import "@/utils/cm-setting.js";
Vue.component("codemirror", codemirror);
@@ -29,89 +29,97 @@
//  import 'vue-codemirror/dist/codemirror.css'
//  Vue.use(VueCodeMirror)
 //实现quill-editor编辑器拖拽上传图片
//实现quill-editor编辑器拖拽上传图片
//  import Quill from 'quill'
import {Quill} from 'vue-quill-editor'
 window.Quill = Quill;
 import imageResize from 'quill-image-resize'
//  const scriptEl = document.createElement('script');
//     scriptEl.charset = 'utf-8'
//     scriptEl.src =  './image-resize.min.js'
//     const head = document.head || document.getElementsByTagName('head')[0];
import { Quill } from "vue-quill-editor";
window.Quill = Quill;
import imageResize from "quill-image-resize";
//  const scriptEl = document.createElement('script');
//     scriptEl.charset = 'utf-8'
//     scriptEl.src =  './image-resize.min.js'
//     const head = document.head || document.getElementsByTagName('head')[0];
//     head.appendChild(scriptEl);
 import { ImageDrop } from 'quill-image-drop-module'
import { ImageDrop } from "quill-image-drop-module";
//  import imageResize from 'quill-image-resize'
 Quill.register('modules/imageDrop', ImageDrop)
Quill.register("modules/imageDrop", ImageDrop);
//  import imageResize from 'quill-image-resize-module'
 Quill.register('modules/imageResize', imageResize)
 //实现quill-editor编辑器调整图片尺寸
Quill.register("modules/imageResize", imageResize);
//实现quill-editor编辑器调整图片尺寸
//  Quill.register('modules/imageResize', ImageResize)
import './assets/icons' // icon
import './permission' // permission control
import LemonIMUI from "lemon-imui";
import "lemon-imui/dist/index.css";
Vue.use(LemonIMUI);
import "./assets/icons"; // icon
import "./permission"; // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
import {
  parseTime,
  resetForm,
  addDateRange,
  selectDictLabel,
  selectDictLabels,
  handleTree,
} from "@/utils/ruoyi";
// åˆ†é¡µç»„ä»¶
import Pagination from "@/components/Pagination";
// è‡ªå®šä¹‰è¡¨æ ¼å·¥å…·ç»„ä»¶
import RightToolbar from "@/components/RightToolbar"
import RightToolbar from "@/components/RightToolbar";
// å¯Œæ–‡æœ¬ç»„ä»¶
import Editor from "@/components/Editor"
import Editor from "@/components/Editor";
// æ–‡ä»¶ä¸Šä¼ ç»„ä»¶
import FileUpload from "@/components/FileUpload"
import FileUpload from "@/components/FileUpload";
// å›¾ç‰‡ä¸Šä¼ ç»„ä»¶
import ImageUpload from "@/components/ImageUpload"
import ImageUpload from "@/components/ImageUpload";
// å›¾ç‰‡é¢„览组件
import ImagePreview from "@/components/ImagePreview"
import ImagePreview from "@/components/ImagePreview";
// å­—典标签组件
import DictTag from '@/components/DictTag'
import DictTag from "@/components/DictTag";
// å¤´éƒ¨æ ‡ç­¾ç»„ä»¶
import VueMeta from 'vue-meta'
import VueMeta from "vue-meta";
// å­—典数据组件
import DictData from '@/components/DictData'
import DictData from "@/components/DictData";
// ç»„件封装集成
import components from './components'
import components from "./components";
// æ³¨å†Œè¿‡æ»¤å™¨
// è‡ªå®šä¹‰æŒ‡ä»¤
import * as directives from './directives'
import * as filters from './filters'
for(let key in filters){
Vue.filter(key, filters[key])
import * as directives from "./directives";
import * as filters from "./filters";
for (let key in filters) {
  Vue.filter(key, filters[key]);
}
// å…¨å±€æ–¹æ³•挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
Vue.prototype.getDicts = getDicts;
Vue.prototype.getConfigKey = getConfigKey;
Vue.prototype.parseTime = parseTime;
Vue.prototype.resetForm = resetForm;
Vue.prototype.addDateRange = addDateRange;
Vue.prototype.selectDictLabel = selectDictLabel;
Vue.prototype.selectDictLabels = selectDictLabels;
Vue.prototype.download = download;
Vue.prototype.handleTree = handleTree;
// å…¨å±€ç»„件挂载
Vue.component('DictTag', DictTag)
Vue.component('Pagination', Pagination)
Vue.component('RightToolbar', RightToolbar)
Vue.component('Editor', Editor)
Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload)
Vue.component('ImagePreview', ImagePreview)
Vue.component("DictTag", DictTag);
Vue.component("Pagination", Pagination);
Vue.component("RightToolbar", RightToolbar);
Vue.component("Editor", Editor);
Vue.component("FileUpload", FileUpload);
Vue.component("ImageUpload", ImageUpload);
Vue.component("ImagePreview", ImagePreview);
// å°è£…自定义指令
for(let key in directives)
Vue.directive(key, directives[key])
Vue.use(directive)
Vue.use(plugins)
Vue.use(VueMeta)
DictData.install()
Vue.use(components)
for (let key in directives) Vue.directive(key, directives[key]);
Vue.use(directive);
Vue.use(plugins);
Vue.use(VueMeta);
DictData.install();
Vue.use(components);
// Vue.use(VueQuillEditor)
/**
 * If you don't want to use mock-server
@@ -123,14 +131,14 @@
 */
Vue.use(Element, {
  size: Cookies.get('size') || 'medium' // set element-ui default size
})
  size: Cookies.get("size") || "medium", // set element-ui default size
});
Vue.config.productionTip = false
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  el: "#app",
  router,
  store,
  render: h => h(App)
})
  render: (h) => h(App),
});
src/views/knowledge/education/index.vue
@@ -137,7 +137,7 @@
                >
              </el-form-item>
            </el-form>
            <el-divider></el-divider>
            <el-row :gutter="10" class="mb8">
              <el-col :span="1.5">
                <el-button
@@ -430,13 +430,7 @@
</template>
<script>
import {
  listUser,
  getUser,
  delUser,
  addUser,
  updateUser,
} from "@/api/system/user";
import { listUser, delUser, addUser, updateUser } from "@/api/system/user";
import { getToken } from "@/utils/auth";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
src/views/knowledge/questionbank/index.vue
@@ -53,7 +53,7 @@
            >
          </el-form-item>
        </el-form>
        <el-divider></el-divider>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
src/views/knowledge/questionnaire/index.vue
@@ -109,7 +109,7 @@
                >
              </el-form-item>
            </el-form>
            <el-divider></el-divider>
            <el-row :gutter="10" class="mb8">
              <el-col :span="1.5">
                <el-button
src/views/repositoryai/matching/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,752 @@
<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!--用户数据-->
      <el-col :span="24" :xs="24">
        <el-form
          :model="topqueryParams"
          ref="queryForm"
          size="small"
          :inline="true"
          v-show="showSearch"
          label-width="98px"
        >
          <el-form-item label="题目文本" prop="text">
            <el-input
              v-model="topqueryParams.text"
              placeholder="请输入"
              clearable
              style="width: 200px"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="关联指标" prop="relevance">
            <el-input
              v-model="topqueryParams.relevance"
              placeholder="请输入"
              clearable
              style="width: 200px"
              @keyup.enter.native="handleQuery"
            /> </el-form-item
          ><el-form-item label="手机号" prop="phonenumber">
            <el-input
              v-model="topqueryParams.phonenumber"
              placeholder="请输入手机号"
              clearable
              style="width: 200px"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <br />
          <el-form-item label="创建时间">
            <el-date-picker
              v-model="dateRange"
              style="width: 240px"
              value-format="yyyy-MM-dd"
              type="daterange"
              range-separator="-"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
            ></el-date-picker>
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              icon="el-icon-search"
              size="medium"
              @click="handleQuery"
              >搜索</el-button
            >
            <el-button icon="el-icon-refresh" size="medium" @click="resetQuery"
              >重置</el-button
            >
          </el-form-item>
        </el-form>
        <el-divider></el-divider>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              size="medium"
              @click="handleAdd"
              v-hasPermi="['system:user:add']"
              >新增</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="success"
              plain
              icon="el-icon-edit"
              size="medium"
              :disabled="single"
              @click="handleUpdate"
              v-hasPermi="['system:user:edit']"
              >修改</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="danger"
              plain
              icon="el-icon-delete"
              size="medium"
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['system:user:remove']"
              >删除</el-button
            >
          </el-col>
          <el-col :span="19">
            <div class="documentf">
              <div class="document">
                <el-button
                  type="warning"
                  plain
                  icon="el-icon-download"
                  size="medium"
                  @click="handleExport"
                  v-hasPermi="['system:user:export']"
                  >导出</el-button
                >
              </div>
            </div>
          </el-col>
          <!-- <el-col :span="1.5"> </el-col> -->
        </el-row>
        <!-- <right-toolbar
            :showSearch.sync="showSearch"
            @queryTable="getList"
            :columns="columns"
          ></right-toolbar> -->
        <el-table
          v-loading="loading"
          :data="userList"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column
            label="序号"
            align="center"
            key="userId"
            prop="userId"
          />
          <el-table-column
            label="姓名"
            align="center"
            key="userName"
            prop="userName"
            :show-overflow-tooltip="true"
          />
          <el-table-column
            label="手机号"
            align="center"
            key="phonenumber"
            prop="phonenumber"
          />
          <el-table-column
            label="模版名称"
            align="center"
            key="templateName"
            prop="templateName"
          />
          <el-table-column
            label="问题文本"
            align="center"
            key="problem"
            prop="problem"
            width="180"
          />
          <el-table-column
            label="问题回复"
            align="center"
            key="replyz"
            prop="replyz"
          />
          <el-table-column
            label="播放语音"
            align="center"
            key="topicnumber"
            prop="topicnumber"
            width="350"
          >
            <template slot-scope="scope">
              <my-audio
                :theUrl="scope.row.url"
                :theControlList="scope.row.controlList"
              ></my-audio>
            </template>
          </el-table-column>
          <el-table-column
            label="匹配成功语句"
            align="center"
            key="replya"
            prop="replya"
          />
          <el-table-column
            label="关联指标"
            align="center"
            key="replys"
            prop="replys"
          />
          <el-table-column
            label="指标值"
            align="center"
            key="replyc"
            prop="replyc"
          />
          <el-table-column
            label="回复时间"
            align="center"
            prop="createTime"
            width="160"
          >
            <template slot-scope="scope">
              <span>{{ parseTime(scope.row.createTime) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            align="center"
            width="180"
            class-name="small-padding fixed-width"
          >
            <template slot-scope="scope">
              <el-button
                size="medium"
                type="text"
                icon="el-icon-edit"
                class="icon-edit"
                @click="Referencequestion(scope.row)"
                v-hasPermi="['system:user:edit']"
                >编辑话术</el-button
              >
              <el-button
                size="medium"
                type="text"
                icon="el-icon-s-claim"
                class="icon-s-claim"
                @click="handleUpdate(scope.row)"
                v-hasPermi="['system:user:edit']"
                >测试匹配</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <pagination
          v-show="total > 0"
          :total="total"
          :page.sync="topqueryParams.pageNum"
          :limit.sync="topqueryParams.pageSize"
          @pagination="getList"
        />
      </el-col>
    </el-row>
    <!-- æ·»åŠ æˆ–ä¿®æ”¹é¢˜ç›®é…ç½®å¯¹è¯æ¡† -->
    <!-- æŒ‡æ ‡ç¼–辑 -->
    <el-dialog :visible.sync="indicatorVisible" width="700px">
      <div class="headline">
        <div class="basics">问题配置</div>
        <div class="headbottom">
          <el-button
            type="primary"
            icon="el-icon-circle-plus-outline"
            @click="addzbiao"
            >添加指标</el-button
          >
          <el-button type="primary" icon="el-icon-s-claim">保存</el-button>
          <el-button type="primary" icon="el-icon-document"
            >更新指标规则至模版</el-button
          >
        </div>
      </div>
      <div class="valuetop" v-for="(item, index) in deployList" :key="item.id">
        <div class="val-text">
          <div>
            æœ‰æ— å¤æŸ¥ <span>{{ item.name }}</span>
          </div>
          <div class="text-icon" @click="deletei(index)">
            <i class="el-icon-delete" />
          </div>
        </div>
        <div class="val-bon">
          <el-form ref="form" :model="form" label-width="80px">
            <el-form-item label="指标类型">
              <el-radio-group v-model="form.resource">
                <el-radio label="选项"></el-radio>
                <el-radio label="文本"></el-radio>
                <el-radio label="数组"></el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="指标名称">
              <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="指标值">
              <el-input v-model="item.name"></el-input>
            </el-form-item>
            <el-form-item label="特殊资源">
              <el-radio-group v-model="form.resource">
                <el-radio label="基础"></el-radio>
                <el-radio label="自定义"></el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="基础规则">
              <el-input type="textarea" v-model="item.valuetop"></el-input>
            </el-form-item>
          </el-form>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="indicatorVisible = false">关闭</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  listUser,
  delUser,
  addUser,
  updateUser,
  changeUserStatus,
} from "@/api/system/user";
import myAudio from "./myAudio.vue";
export default {
  name: "User",
  dicts: ["sys_normal_disable", "sys_user_sex"],
  components: { myAudio },
  data() {
    return {
      // é®ç½©å±‚
      loading: true,
      // é€‰ä¸­æ•°ç»„
      ids: [],
      // éžå•个禁用
      single: true,
      // éžå¤šä¸ªç¦ç”¨
      multiple: true,
      // æ˜¾ç¤ºæœç´¢æ¡ä»¶
      showSearch: true,
      // æ€»æ¡æ•°
      total: 0,
      // ç”¨æˆ·è¡¨æ ¼æ•°æ®
      userList: [
        {
          userId: 1,
          userName: "王五",
          phonenumber: "13802963330",
          templateName: "乌拉",
          problem: "最近怎么样",
          reply: "sas",
          url: "",
          controlList: "onlyOnePlaying",
        },
        {
          userId: 1,
          userName: "张五",
          phonenumber: "13802963330",
          templateName: "乌拉",
          problem: "最近怎么样",
          reply: "sas",
          url: "",
          controlList: "onlyOnePlaying",
        },
      ],
      deployList: [
        {
          id: 1,
          name: "有",
          valuetop:
            "(?!.*忘|.*不|.*没)^.*(是|有|对|做|作|检|查|复诊|好|参加|复诊|去(过|好|了|完|医院)|来(过|了|医院))|没错|对呀|可能|(已经|早)去了|开了药|腰带|吊带|要的|(?<!没)有的|表带,10;要,5",
        },
        {
          id: 2,
          name: "不知道",
          valuetop:
            "(不|没|谁|鬼|怎么).*(病|可能|知道|了解|清楚|懂|明白|确认|确定|晓得|知晓|认得|识得|印象|熟悉|è®°|会|关心|关注|注意|告诉|通知|听)",
        },
      ],
      // å¼¹å‡ºå±‚标题
      title: "",
      // æ—¥æœŸèŒƒå›´
      dateRange: [],
      inputValue: "",
      indicatorVisible: false, //指标编辑弹框
      radio: "",
      radios: [],
      previewtype: 2, //预览题目类型
      total: 0, // æ€»æ¡æ•°
      ImportQuantity: 999, //导题目数量
      //预览题目信息
      previewvalue: {
        username: "这个医生对你怎么样",
      },
      // è¡¨å•参数
      form: {
        phonenumber: "",
        totagid: "",
        types: "",
        nickName: "",
        qystatus: "",
        btstatus: "",
      },
      //导入进度
      dractive: 1,
      // å¯¼å…¥å±•示表单
      uploadingData: {},
      // æŸ¥è¯¢å‚æ•°
      topqueryParams: {
        pageNum: 1,
        pageSize: 10,
        userName: undefined,
        tagid: undefined,
        topic: undefined,
      },
      propss: { multiple: true },
      // è¡¨å•校验
      rules: {
        userName: [
          { required: true, message: "用户名称不能为空", trigger: "blur" },
          {
            min: 2,
            max: 20,
            message: "用户名称长度必须介于 2 å’Œ 20 ä¹‹é—´",
            trigger: "blur",
          },
        ],
        nickName: [
          { required: true, message: "用户昵称不能为空", trigger: "blur" },
        ],
        password: [
          { required: true, message: "用户密码不能为空", trigger: "blur" },
          {
            min: 5,
            max: 20,
            message: "用户密码长度必须介于 5 å’Œ 20 ä¹‹é—´",
            trigger: "blur",
          },
        ],
        email: [
          {
            type: "email",
            message: "请输入正确的邮箱地址",
            trigger: ["blur", "change"],
          },
        ],
        phonenumber: [
          {
            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
            message: "请输入正确的手机号码",
            trigger: "blur",
          },
        ],
        IDnumber: [
          {
            pattern:
              /^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))(\d|X|x)$/,
            message: "请输入正确的身份证号码",
            trigger: "blur",
          },
        ],
      },
    };
  },
  watch: {},
  created() {
    this.getList();
  },
  methods: {
    /** æŸ¥è¯¢é¢˜ç›®åˆ—表 */
    getList() {
      this.loading = true;
      listUser(this.addDateRange(this.topqueryParams, this.dateRange)).then(
        (response) => {
          // this.userList = response.rows;
          this.total = response.total;
          this.loading = false;
        }
      );
    },
    // ç¼–辑话术指标
    Referencequestion(row) {
      this.indicatorVisible = true;
    },
    // æ–°å¢žæŒ‡æ ‡
    addzbiao() {
      const ids = this.deployList.length + 1;
      console.log(ids);
      this.deployList.push({
        id: ids,
        name: "",
        valuetop: "",
      });
    },
    // åˆ é™¤æŒ‡æ ‡
    deletei(index) {
      console.log(index);
      this.deployList.splice(index, 1);
    },
    // é¢˜ç›®çŠ¶æ€ä¿®æ”¹
    handleStatusChange(row) {
      let text = row.status === "0" ? "启用" : "停用";
      this.$modal
        .confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
        .then(function () {
          return changeUserStatus(row.userId, row.status);
        })
        .then(() => {
          this.$modal.msgSuccess(text + "成功");
        })
        .catch(function () {
          row.status = row.status === "0" ? "1" : "0";
        });
    },
    // å–消按钮
    cancel() {
      this.reset();
    },
    // è¡¨å•重置
    reset() {
      this.form = {
        userId: undefined,
        deptId: undefined,
        userName: undefined,
        nickName: undefined,
        password: undefined,
        phonenumber: undefined,
        email: undefined,
        sex: undefined,
        status: "0",
        remark: undefined,
        postIds: [],
        roleIds: [],
      };
      this.resetForm("form");
    },
    /** æœç´¢æŒ‰é’®æ“ä½œ */
    handleQuery() {
      this.topqueryParams.pageNum = 1;
      this.getList();
    },
    /** é‡ç½®æŒ‰é’®æ“ä½œ */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.topqueryParams.deptId = undefined;
      this.$refs.tree.setCurrentKey(null);
      this.handleQuery();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.userId);
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    //删除选项
    handleClose(tag) {
      this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
    },
    /** æ–°å¢žæŒ‰é’®æ“ä½œ */
    handleAdd() {
      this.reset();
    },
    /** ä¿®æ”¹æŒ‰é’®æ“ä½œ */
    handleUpdate(row) {
      this.reset();
    },
    /** æäº¤æŒ‰é’® */
    submitForm: function () {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.form.userId != undefined) {
            updateUser(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addUser(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** åˆ é™¤æŒ‰é’®æ“ä½œ */
    handleDelete(row) {
      const userIds = row.userId || this.ids;
      this.$modal
        .confirm('是否确认删除用户编号为"' + userIds + '"的数据项?')
        .then(function () {
          return delUser(userIds);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
      this.download(
        "system/user/export",
        {
          ...this.topqueryParams,
        },
        `user_${new Date().getTime()}.xlsx`
      );
    },
  },
};
</script>
<style lang="scss" scoped>
.el-button--primary.is-plain {
  color: #ffffff;
  background: #409eff;
  border-color: #4fabe9;
}
.document {
  width: 100px;
  height: 50px;
}
.documentf {
  display: flex;
  justify-content: flex-end;
}
.download {
  text-align: center;
  .el-upload__tip {
    font-size: 23px;
  }
  .el-upload__text {
    font-size: 23px;
  }
}
.uploading {
  margin-top: 20px;
  margin: 20px;
  padding: 30px;
  background: #ffffff;
  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);
}
.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;
}
.drexamine {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30px;
  background: #daeaf5;
  img {
    width: 100px;
    height: 100px;
  }
}
.qrcode-dialo {
  // text-align: center;
  //   display: flex;
  margin: 20px;
  padding: 30px;
  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);
  .topic-dev {
    margin-bottom: 25px;
    font-size: 20px !important;
    .dev-text {
      margin-bottom: 10px;
    }
  }
}
.headline {
  display: flex;
  height: 50px;
  margin: 15px;
  margin-bottom: 0;
  padding: 0 20px 20px 20px;
  line-height: 50px;
  background: #92c5f0;
  justify-content: space-between;
}
.valuetop {
  .val-text {
    display: flex;
    height: 50px;
    margin: 15px;
    margin-bottom: 0;
    // padding: 0 20px 20px 20px;
    padding: 0 20px;
    align-items: center;
    background: #92c5f0;
    justify-content: space-between;
    .text-icon {
      width: 35px;
      height: 35px;
      line-height: 35px;
      text-align: center;
      background: #fafafa;
      cursor: pointer;
      border-radius: 5px;
    }
  }
  .val-bon {
    margin: 15px;
    margin-top: 0;
    padding: 30px;
    background: #f2f5fc;
    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);
  }
}
.icon-s-claim {
  color: #409eff;
}
.icon-edit {
  color: rgb(5, 212, 212);
}
::v-deep.el-radio-group {
  span {
    font-size: 24px;
  }
}
::v-deep.el-checkbox-group {
  span {
    font-size: 24px;
  }
}
</style>
src/views/repositoryai/matching/myAudio.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,288 @@
<template>
  <div
    class="di main-wrap"
    v-loading="audio.waiting"
    element-loading-text="音视频加载中"
    element-loading-spinner="el-icon-loading"
  >
    <!-- è¿™é‡Œè®¾ç½®äº†ref属性后,在vue组件中,就可以用this.$refs.audio来访问该dom元素 -->
    <audio
      ref="audio"
      class="dn"
      :src="url"
      :preload="audio.preload"
      @play="onPlay"
      @error="onError"
      @waiting="onWaiting"
      @pause="onPause"
      @timeupdate="onTimeupdate"
      @loadedmetadata="onLoadedmetadata"
    ></audio>
    <div>
      <!-- æ’­æ”¾ -->
      <i
        class="el-icon-microphone"
        v-if="audio.playing == true"
        style="color: rgb(10 243 61); font-size: 18px"
      ></i>
      <i class="el-icon-microphone" v-else style="font-size: 18px"></i>
      <el-button style="margin: 0 10px" type="text" @click="startPlayOrPause">{{
        audio.playing | transPlayPause
      }}</el-button>
      <!-- æ’­æ”¾æœ€å¤§æ—¶é—´ -->
      <span type="info">{{ audio.maxTime | formatSecond }}</span>
      <!-- å¿«è¿›æŒ‰é’® -->
      <el-button
        v-show="!controlList.noSpeed"
        type="text"
        @click="changeSpeed"
        >{{ audio.speed | transSpeed }}</el-button
      >
      <a
        :href="url"
        v-show="!controlList.noDownload"
        target="_blank"
        class="download"
        download
        >下载</a
      >
      <br />
      <!-- æ’­æ”¾æ—¶é—´ -->
      <!-- <el-tag type="info">{{ audio.currentTime | formatSecond }}</el-tag> -->
      <!-- æ’­æ”¾è¿›åº¦æ¡ -->
      <el-slider
        v-show="!controlList.noProcess"
        v-model="sliderTime"
        :format-tooltip="formatProcessToolTip"
        @change="changeCurrentTime"
        class="slider"
      ></el-slider>
      <!-- é™éŸ³æŒ‰é’® -->
      <!-- <el-button
        v-show="!controlList.noMuted"
        type="text"
        @click="startMutedOrNot"
        >{{ audio.muted | transMutedOrNot }}</el-button
      > -->
      <!-- éŸ³é‡å¤§å° -->
      <el-slider
        v-show="!controlList.noVolume"
        v-model="volume"
        :format-tooltip="formatVolumeToolTip"
        @change="changeVolume"
        class="slider"
      ></el-slider>
    </div>
  </div>
</template>
<script>
function realFormatSecond(second) {
  var secondType = typeof second;
  if (secondType === "number" || secondType === "string") {
    second = parseInt(second);
    var hours = Math.floor(second / 3600);
    second = second - hours * 3600;
    var mimute = Math.floor(second / 60);
    second = second - mimute * 60;
    return (
      hours + ":" + ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2)
    );
  } else {
    return "0:00:00";
  }
}
export default {
  // çˆ¶ä¼ å­
  props: {
    theUrl: {
      type: String,
      required: true,
    },
    theSpeeds: {
      type: Array,
      default() {
        return [1, 1.5, 2];
      },
    },
    theControlList: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      url: this.theUrl,
      audio: {
        currentTime: 0,
        maxTime: 0, // éŸ³é¢‘æ—¶é•¿
        playing: false, // æ˜¯å¦åœ¨æ’­æ”¾
        muted: false,
        speed: 1,
        waiting: false,
        preload: "auto",
      },
      sliderTime: 0,
      volume: 100,
      speeds: this.theSpeeds,
      controlList: {
        // ä¸æ˜¾ç¤ºä¸‹è½½
        noDownload: false,
        // ä¸æ˜¾ç¤ºé™éŸ³
        noMuted: false,
        // ä¸æ˜¾ç¤ºéŸ³é‡æ¡
        noVolume: false,
        // ä¸æ˜¾ç¤ºè¿›åº¦æ¡
        noProcess: false,
        // åªèƒ½æ’­æ”¾ä¸€ä¸ª
        onlyOnePlaying: false,
        // ä¸è¦å¿«è¿›æŒ‰é’®
        noSpeed: false,
      },
    };
  },
  methods: {
    changeSpeed() {
      let index = this.speeds.indexOf(this.audio.speed) + 1;
      this.audio.speed = this.speeds[index % this.speeds.length];
      this.$refs.audio.playbackRate = this.audio.speed;
    },
    startMutedOrNot() {
      this.$refs.audio.muted = !this.$refs.audio.muted;
      this.audio.muted = this.$refs.audio.muted;
    },
    // éŸ³é‡æ¡toolTip
    formatVolumeToolTip(index) {
      return "音量条: " + index;
    },
    // è¿›åº¦æ¡toolTip
    formatProcessToolTip(index = 0) {
      index = parseInt((this.audio.maxTime / 100) * index);
      return "进度条: " + realFormatSecond(index);
    },
    // éŸ³é‡æ”¹å˜
    changeVolume(index = 0) {
      this.$refs.audio.volume = index / 100;
      this.volume = index;
    },
    // æ’­æ”¾è·³è½¬
    changeCurrentTime(index) {
      this.$refs.audio.currentTime = parseInt(
        (index / 100) * this.audio.maxTime
      );
    },
    //显示播放或者暂停
    startPlayOrPause() {
      return this.audio.playing ? this.pausePlay() : this.startPlay();
    },
    // å¼€å§‹æ’­æ”¾
    startPlay() {
      // console.log("播放");
      this.$refs.audio.play();
    },
    // æš‚停播放
    pausePlay() {
      // console.log("暂停");
      this.$refs.audio.pause();
    },
    // éŸ³é¢‘暂停时触发
    onPause() {
      this.audio.playing = false;
    },
    // éŸ³é¢‘错误时触发
    onError() {
      //   this.audio.waiting = true;
    },
    // éŸ³é¢‘准备时触发
    onWaiting(res) {
      console.log("等待", res);
    },
    // éŸ³é¢‘播放时触发
    onPlay(res) {
      // console.log("播放", res);
      this.audio.playing = true;
      this.audio.loading = false;
      if (!this.controlList.onlyOnePlaying) {
        return;
      }
      let target = res.target;
      let audios = document.getElementsByTagName("audio"); //获取所有视频标签
      [...audios].forEach((item) => {
        if (item !== target) {
          item.pause();
        }
      });
    },
    // æ’­æ”¾æ•°é‡é™åˆ¶ï¼ˆåŒæ—¶åªèƒ½æ’­æ”¾ä¸€ä¸ªï¼‰
    setControlList() {
      // æ³¨æ„çˆ¶ç»„件传的值是否满足要求
      let controlList = this.theControlList.split(" ");
      controlList.forEach((item) => {
        if (this.controlList[item] !== undefined) {
          this.controlList[item] = true;
        }
      });
    },
    // å½“timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
    onTimeupdate(res) {
      this.audio.currentTime = res.target.currentTime;
      this.sliderTime = parseInt(
        (this.audio.currentTime / this.audio.maxTime) * 100
      );
    },
    // å½“加载语音流元数据完成后,会触发该事件的回调函数
    onLoadedmetadata(res) {
      // console.log("加载", res);
      this.audio.waiting = false; // å–消等待状态
      this.audio.maxTime = parseInt(res.target.duration);
    },
  },
  // è¿‡æ»¤å±žæ€§
  filters: {
    formatSecond(second = 0) {
      return realFormatSecond(second);
    },
    transPlayPause(value) {
      return value ? "暂停" : "播放";
    },
    transMutedOrNot(value) {
      return value ? "放音" : "静音";
    },
    transSpeed(value) {
      return "快进: x" + value;
    },
  },
  created() {
    this.setControlList();
  },
};
</script>
<style scoped>
.slider {
  display: inline-block;
  width: 100px;
  position: relative;
  top: 14px;
  margin-left: 15px;
}
.di {
  display: inline-block;
}
.download {
  color: #409eff;
  margin-left: 15px;
}
.dn {
  display: none;
}
</style>
src/views/repositoryai/verbaltrick/particulars/index.vue
@@ -136,7 +136,7 @@
  margin-bottom: 0;
  padding: 0 20px 20px 20px;
  line-height: 50px;
  background: #cdcdce;
  background: #92c5f0;
}
.headline {
  display: flex;
@@ -145,7 +145,7 @@
  margin-bottom: 0;
  padding: 0 20px 20px 20px;
  line-height: 50px;
  background: #cdcdce;
  background: #92c5f0;
  justify-content: space-between;
}
.valuetop {
@@ -157,7 +157,7 @@
    // padding: 0 20px 20px 20px;
    padding: 0 20px;
    align-items: center;
    background: #cdcdce;
    background: #92c5f0;
    justify-content: space-between;
    .text-icon {
      width: 35px;
src/views/shortmessage/communication/database/contacts.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,148 @@
export default [
    {
      id: 1,
      displayName: "像梦一样自由",
      avatar: "https://p.qqan.com/up/2020-2/2020022821001845128.jpg",
      index: "X",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: "你开心吗"
    },
    {
      id: 2,
      displayName: "梦醒时分、",
      avatar: "https://p.qqan.com/up/2021-1/20211301122243621.jpg",
      index: "M",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 3,
      displayName: "凌云",
      avatar: "https://p.qqan.com/up/2021-1/2021129102387841.jpg",
      index: "L",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 4,
      displayName: "小郭",
      avatar: "https://p.qqan.com/up/2021-1/2021122135507881.jpg",
      index: "X",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 5,
      displayName: "杨玉泉",
      avatar: "https://p.qqan.com/up/2021-1/20211211131598147.jpg",
      index: "Y",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 6,
      displayName: "森系Style",
      avatar: "https://p.qqan.com/up/2021-1/2021113104111220.jpg",
      index: "S",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 7,
      displayName: "霸王花",
      avatar: "https://p.qqan.com/up/2021-1/20211411391666.jpg",
      index: "B",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: "你怎么还不睡呀?"
    },
    {
      id: 8,
      displayName: "曾平",
      avatar: "https://p.qqan.com/up/2020-12/202012291044425822.jpg",
      index: "Z",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 9,
      displayName: "淡然",
      avatar: "https://p.qqan.com/up/2020-12/202012141813343503.jpg",
      index: "D",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 10,
      displayName: "叶子。",
      avatar: "https://p.qqan.com/up/2021-1/20211301122243621.jpg",
      index: "Y",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 11,
      displayName: "土豆",
      avatar: "https://p.qqan.com/up/2020-12/202012111157268739.jpg",
      index: "T",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 12,
      displayName: "清沫",
      avatar: "https://p.qqan.com/up/2020-12/202012415467996.jpg",
      index: "Q",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    },
    {
      id: 13,
      displayName: "Lemon-imui交流群",
      avatar: "https://p.qqan.com/up/2020-11/20201127157109035.jpg",
      index: "L",
      isGroup: true,
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: "这个咋处理啊?"
    },
    {
      id: 14,
      displayName: "系统通知",
      avatar: "https://p.qqan.com/up/2020-6/2020061117234279854.jpg",
      index: "[1]系統通知",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: "宁静致远通过了你的好友请求",
      renderContainer() {
        return (
          <div style="padding:15px;">
            <div>宁静致远通过了你的好友请求</div>
            <div>宁静致远通过了你的好友请求</div>
            <div>宁静致远通过了你的好友请求</div>
          </div>
        );
      }
    },
    {
      id: 15,
      displayName: "宁静致远。",
      avatar: "https://p.qqan.com/up/2020-6/2020060308522797777.jpg",
      index: "N",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: ""
    }
  ];
src/views/shortmessage/communication/database/emoji.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,293 @@
export default [
    {
      label: "表情",
      children: [
        {
          name: "1f600",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f600.png"
        },
        {
          name: "1f62c",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f62c.png"
        },
        {
          name: "1f601",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f601.png"
        },
        {
          name: "1f602",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f602.png"
        },
        {
          name: "1f923",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f923.png"
        },
        {
          name: "1f973",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f973.png"
        },
        {
          name: "1f603",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f603.png"
        },
        {
          name: "1f604",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f604.png"
        },
        {
          name: "1f605",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f605.png"
        },
        {
          name: "1f606",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f606.png"
        },
        {
          name: "1f607",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f607.png"
        },
        {
          name: "1f609",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f609.png"
        },
        {
          name: "1f60a",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f60a.png"
        },
        {
          name: "1f642",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f642.png"
        },
        {
          name: "1f643",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f643.png"
        },
        {
          name: "1263a",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/263a.png"
        },
        {
          name: "1f60b",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f60b.png"
        },
        {
          name: "1f60c",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f60c.png"
        },
        {
          name: "1f60d",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f60d.png"
        },
        {
          name: "1f970",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f970.png"
        },
        {
          name: "1f618",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f618.png"
        },
        {
          name: "1f617",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f617.png"
        },
        {
          name: "1f619",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f619.png"
        },
        {
          name: "1f61a",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f61a.png"
        },
        {
          name: "1f61c",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f61c.png"
        },
        {
          name: "1f92a",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f92a.png"
        },
        {
          name: "1f928",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f928.png"
        },
        {
          name: "1f9d0",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f9d0.png"
        },
        {
          name: "1f61d",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f61d.png"
        },
        {
          name: "1f61b",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f61b.png"
        },
        {
          name: "1f911",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f911.png"
        },
        {
          name: "1f913",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f913.png"
        },
        {
          name: "1f60e",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f60e.png"
        },
        {
          name: "1f929",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f929.png"
        },
        {
          name: "1f921",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f921.png"
        },
        {
          name: "1f920",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f920.png"
        },
        {
          name: "1f917",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f917.png"
        },
        {
          name: "1f60f",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f60f.png"
        },
        {
          name: "1f636",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f636.png"
        },
        {
          name: "1f610",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f610.png"
        },
        {
          name: "1f611",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f611.png"
        },
        {
          name: "1f612",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f612.png"
        },
        {
          name: "1f644",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f644.png"
        },
        {
          name: "1f914",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f914.png"
        },
        {
          name: "1f925",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f925.png"
        },
        {
          name: "1f92d",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f92d.png"
        },
        {
          name: "1f92b",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f92b.png"
        },
        {
          name: "1f92c",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f92c.png"
        },
        {
          name: "1f92f",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f92f.png"
        },
        {
          name: "1f633",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f633.png"
        },
        {
          name: "1f61e",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f61e.png"
        },
        {
          name: "1f61f",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f61f.png"
        },
        {
          name: "1f620",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f620.png"
        },
        {
          name: "1f621",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f621.png"
        }
      ]
    },
    {
      label: "收藏",
      children: [
        {
          name: "1f62c",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f62c.png"
        },
        {
          name: "1f621",
          title: "微笑",
          src: "https://twemoji.maxcdn.com/2/72x72/1f621.png"
        }
      ]
    }
  ];
src/views/shortmessage/communication/database/messages.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
import ContactsData from "./contacts";
import UserData from "./user";
const generateRandId = () => {
  return Math.random().toString(36).substr(-8);
};
const getContact = (id) => {
  const data = ContactsData.find((contact) => contact.id == id);
  return { id: data.id, avatar: data.avatar, displayName: data.displayName };
};
export default {
  1: [
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "问你件事",
      toContactId: 1,
      fromUser: UserData
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "啥子。",
      toContactId: 1,
      fromUser: getContact(1)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "为什么",
      toContactId: 1,
      fromUser: UserData
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "你穿了高跟鞋还这么矮",
      toContactId: 1,
      fromUser: UserData
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "因为我矮啊。[!1f600][!1f600][!1f600]",
      toContactId: 1,
      fromUser: getContact(1)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "你开心吗",
      toContactId: 1,
      fromUser: getContact(1)
    }
  ],
  2: [],
  3: [],
  4: [],
  5: [],
  6: [],
  7: [],
  8: [],
  9: [],
  10: [],
  11: [],
  12: [],
  13: [
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "我是测试时候看到的",
      toContactId: 1,
      fromUser: getContact(4)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "上新版本了,玩玩",
      toContactId: 1,
      fromUser: getContact(4)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "项目内没有搞这个",
      toContactId: 1,
      fromUser: getContact(4)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "@awesome æœ€æ–°çš„,不然哪有这功能",
      toContactId: 1,
      fromUser: getContact(5)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "其实是跟你的遮罩层有冲突",
      toContactId: 1,
      fromUser: getContact(4)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "自己修改index哈",
      toContactId: 1,
      fromUser: UserData
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "你们升级到最近版了吗?",
      toContactId: 1,
      fromUser: getContact(6)
    },
    {
      id: generateRandId(),
      status: "succeed",
      type: "text",
      sendTime: 1566047865417,
      content: "wo çŽ°åœ¨ç”¨çš„142",
      toContactId: 1,
      fromUser: getContact(7)
    }
  ],
  14: [],
  15: []
};
src/views/shortmessage/communication/database/user.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
export default {
    id: 1000,
    avatar: "https://p.qqan.com/up/2018-4/15244505348390471.jpg",
    displayName: "野火。"
  };
src/views/shortmessage/communication/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,908 @@
<template>
  <div id="app">
    <div class="scroll-top" @click="scrollToTop">🚀</div>
    <div class="imui-center">
      <lemon-imui
        :user="user"
        ref="IMUI"
        :contextmenu="contextmenu"
        :contact-contextmenu="contactContextmenu"
        :theme="theme"
        :hide-menu="hideMenu"
        :hide-menu-avatar="hideMenuAvatar"
        :hide-message-name="hideMessageName"
        :hide-message-time="hideMessageTime"
        @change-menu="handleChangeMenu"
        @change-contact="handleChangeContact"
        @pull-messages="handlePullMessages"
        @message-click="handleMessageClick"
        @menu-avatar-click="handleMenuAvatarClick"
        @send="handleSend"
      >
        <template #cover>
          <div class="cover">
            <i class="lemon-icon-message"></i>
            <p><b>自定义封面 Lemon</b> IMUI</p>
          </div>
        </template>
        <template #message-title="contact">
          <span>{{ contact.displayName }}</span>
          <small class="more" @click="changeDrawer(contact, $refs.IMUI)"
            >{{
              ($refs.IMUI ? $refs.IMUI.drawerVisible : false) ? "关闭" : "打开"
            }}抽屉</small
          >
          <br />
        </template>
      </lemon-imui>
      <div class="action">
        <lemon-button @click="appendMessage">发送消息</lemon-button>
        <lemon-button @click="appendEventMessage">发送 event æ¶ˆæ¯</lemon-button>
        <lemon-button @click="removeMessage">删除最近一条消息</lemon-button>
        <lemon-button @click="updateMessage">修改消息</lemon-button>
        <lemon-button @click="appendCustomMessage">发送消息</lemon-button>
        <br />
        <lemon-button @click="updateContact">修改联系人信息</lemon-button>
        <lemon-button @click="changeMenuVisible">切换导航显示</lemon-button>
        <lemon-button @click="changeMenuAvatarVisible"
          >切换头像显示</lemon-button
        >
        <lemon-button @click="changeMessageNameVisible"
          >切换聊天窗口内名字显示</lemon-button
        >
        <lemon-button @click="changeMessageTimeVisible"
          >切换聊天窗口内时间显示</lemon-button
        >
        <lemon-button @click="changeTheme"
          >切换主题,当前主题:{{ this.theme }}</lemon-button
        >
      </div>
    </div>
  </div>
</template>
<script>
import LemonMessageVoice from "./lemon-message-voice";
import EmojiData from "./database/emoji";
import { sendWebsocket, closeWebsocket } from "@/websocket/websocket.js";
// Vue.component(LemonMessageVoice.name, LemonMessageVoice);
// èŽ·å–æ—¶é—´
const getTime = () => {
  return new Date().getTime();
};
// éšæœºid
const generateRandId = () => {
  return Math.random().toString(36).substr(-8);
};
// éšæœºå­—符
const generateRandWord = () => {
  return Math.random().toString(36).substr(2);
};
// èŽ·å–æ¶ˆæ¯
const generateMessage = (toContactId = "", fromUser) => {
  if (!fromUser) {
    fromUser = {
      id: "system",
      displayName: "系统测试",
      avatar: "http://upload.qqbodys.com/allimg/1710/1035512943-0.jpg",
    };
  }
  return {
    id: generateRandId(),
    status: "succeed",
    type: "text",
    sendTime: getTime(),
    content: generateRandWord(),
    //fileSize: 1231,
    //fileName: "asdasd.doc",
    toContactId,
    fromUser,
  };
};
export default {
  name: "communication",
  data() {
    return {
      theme: "blue",
      // è”系人右键操作
      contactContextmenu: [
        {
          text: "删除该聊天",
          click: (e, instance, hide) => {
            const { IMUI, contact } = instance;
            IMUI.updateContact({
              id: contact.id,
              lastContent: null,
            });
            if (IMUI.currentContactId == contact.id) IMUI.changeContact(null);
            hide();
          },
        },
        {
          text: "设置备注和标签",
        },
        {
          text: "投诉",
        },
        {
          icon: "lemon-icon-message",
          render: (h, instance, hide) => {
            return (
              <div style="display:flex;justify-content:space-between;align-items:center;width:130px">
                <span>加入黑名单</span>
                <span>
                  <input type="checkbox" id="switch" />
                  <label id="switch-label" for="switch">
                    Toggle
                  </label>
                </span>
              </div>
            );
          },
        },
        {
          click(e, instance, hide) {
            const { IMUI, contact } = instance;
            IMUI.removeContact(contact.id);
            if (IMUI.currentContactId == contact.id) IMUI.changeContact(null);
            hide();
          },
          color: "red",
          text: "删除好友",
        },
      ],
      // æ¶ˆæ¯å³é”®æ“ä½œ
      contextmenu: [
        {
          click: (e, instance, hide) => {
            const { IMUI, message } = instance;
            const data = {
              id: generateRandId(),
              type: "event",
              //使用 jsx æ—¶ click必须使用箭头函数(使上下文停留在vue内)
              content: (
                <div>
                  <span>
                    ä½ æ’¤å›žäº†ä¸€æ¡æ¶ˆæ¯{" "}
                    <span
                      v-show={message.type == "text"}
                      style="color:#333;cursor:pointer"
                      content={message.content}
                      on-click={(e) => {
                        IMUI.setEditorValue(e.target.getAttribute("content"));
                      }}
                    >
                      é‡æ–°ç¼–辑
                    </span>
                  </span>
                </div>
              ),
              toContactId: message.toContactId,
              sendTime: getTime(),
            };
            IMUI.removeMessage(message.id);
            IMUI.appendMessage(data, true);
            hide();
          },
          visible: (instance) => {
            return instance.message.fromUser.id == this.user.id;
          },
          text: "撤回消息",
        },
        {
          visible: (instance) => {
            return instance.message.fromUser.id != this.user.id;
          },
          text: "举报",
        },
        {
          text: "转发",
        },
        {
          visible: (instance) => {
            return instance.message.type == "text";
          },
          text: "复制文字",
        },
        {
          visible: (instance) => {
            return instance.message.type == "image";
          },
          text: "下载图片",
        },
        {
          visible: (instance) => {
            return instance.message.type == "file";
          },
          text: "下载文件",
        },
        {
          click: (e, instance, hide) => {
            const { IMUI, message } = instance;
            IMUI.removeMessage(message.id);
            hide();
          },
          icon: "lemon-icon-folder",
          color: "red",
          text: "删除",
        },
      ],
      packageData: "",
      hideMenuAvatar: false,
      hideMenu: false,
      hideMessageName: false,
      hideMessageTime: true,
      user: {
        id: "1",
        displayName: "June",
        avatar: "",
      },
    };
  },
  created() {},
  mounted() {
    const contactData1 = {
      id: "contact-1",
      displayName: "工作协作群",
      avatar: "http://upload.qqbodys.com/img/weixin/20170804/ji5qxg1am5ztm.jpg",
      index: "[1]群组",
      unread: 0,
      lastSendTime: 1566047865417,
      lastContent: "2",
    };
    const contactData2 = {
      id: "contact-2",
      displayName: "自定义内容",
      avatar: "http://upload.qqbodys.com/img/weixin/20170807/jibfvfd00npin.jpg",
      //index: "Z",
      click(next) {
        next();
      },
      renderContainer: () => {
        return <h1 style="text-indent:20px">自定义页面</h1>;
      },
      lastSendTime: 1345209465000,
      lastContent: "12312",
      unread: 2,
    };
    const contactData3 = {
      id: "contact-3",
      displayName: "铁牛",
      avatar: "http://upload.qqbodys.com/img/weixin/20170803/jiq4nzrkrnd0e.jpg",
      index: "T",
      unread: 32,
      lastSendTime: 3,
      lastContent: "你好123",
    };
    const contactData4 = {
      id: "contact-4",
      displayName: "如花",
      avatar:
        "https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4275424924,2201401076&fm=111&gp=0.jpg",
      index: "",
      unread: 1,
      lastSendTime: 3,
      lastContent: "吃饭了嘛",
    };
    const { IMUI } = this.$refs;
    setTimeout(() => {
      IMUI.changeContact("contact-1");
    }, 500);
    IMUI.setLastContentRender("event", (message) => {
      return `[自定义通知内容]`;
    });
    let contactList = [
      { ...contactData1 },
      { ...contactData2 },
      { ...contactData3 },
      //...Array(100).fill(contactData1)
    ];
    IMUI.initContacts(contactList);
    IMUI.initMenus([
      {
        name: "messages",
      },
      {
        name: "contacts",
      },
      {
        name: "custom1",
        title: "自定义按钮1",
        unread: 0,
        render: (menu) => {
          return <i class="lemon-icon-attah" />;
        },
        renderContainer: () => {
          return (
            <div class="article">
              <ul>
                <li class="article-item">
                  <h2>人民日报谈网红带货:产品真的值得买吗?</h2>
                </li>
                <li class="article-item">
                  ç”˜è‚ƒå¤æ²³åŽ¿å‘ç”Ÿ5.7级地震 æš‚未接到人员伤亡报告
                </li>
                <li class="article-item">
                  åŒ—方多地风力仍强沙尘相伴,东北内蒙古等地迎雨雪
                </li>
                <li class="article-item">
                  è‹±è´§è½¦æ¡ˆï¼šè¶Šå—警方采集疑死者家属DNA作比对
                </li>
                <li class="article-item">
                  çŸ¥åè¿žé”å’–啡店的蛋糕吃出活虫 æ›å…‰å†…幕太震惊
                </li>
              </ul>
              <lemon-contact
                props={{ contact: contactData1 }}
                style="margin:20px"
              />
              <lemon-contact
                props={{ contact: contactData3 }}
                style="margin:20px"
              />
            </div>
          );
        },
        isBottom: true,
      },
      {
        name: "custom2",
        title: "自定义按钮2",
        unread: 0,
        click: () => {
          alert("拦截导航点击事件");
        },
        render: (menu) => {
          return <i class="lemon-icon-group" />;
        },
        isBottom: true,
      },
    ]);
    IMUI.initEditorTools([
      {
        name: "emoji",
      },
      {
        name: "uploadFile",
      },
      {
        name: "uploadImage",
      },
      {
        name: "test1",
        click: () => {
          IMUI.$refs.editor.selectFile("application/vnd.ms-excel");
        },
        render: () => {
          return <span>Excel</span>;
        },
      },
      {
        name: "test1",
        click: () => {
          IMUI.initEditorTools([{ name: "uploadFile" }, { name: "emoji" }]);
        },
        render: () => {
          return <span>重制工具栏</span>;
        },
      },
      {
        name: "test2",
        isRight: true,
        title: "上传 Excel",
        click: () => {
          alert("点击了 Â·Â·Â· ");
        },
        render: () => {
          return <b>···</b>;
        },
      },
    ]);
    IMUI.initEmoji(EmojiData);
    IMUI.setLastContentRender("voice", (message) => {
      return <span>[语音]</span>;
    });
    const { SimpleIMUI } = this.$refs;
    contactData1.id = "11";
    SimpleIMUI.initContacts([contactData1]);
    SimpleIMUI.initEmoji(EmojiData);
    SimpleIMUI.changeContact(contactData1.id);
  },
  methods: {
    changeTheme() {
      this.theme = this.theme == "default" ? "blue" : "default";
    },
    scrollToTop() {
      document.body.scrollIntoView();
    },
    // ç‚¹å‡»å·¦ä¾§å¯¼èˆªå¤´åƒè§¦å‘
    handleMenuAvatarClick() {
      console.log("Event:menu-avatar-click");
    },
    // ç‚¹å‡»æ¶ˆæ¯è§¦å‘
    handleMessageClick(e, key, message, instance) {
      console.log("点击了消息", e, key, message);
      if (key == "status") {
        instance.updateMessage({
          id: message.id,
          status: "going",
          content: "正在重新发送消息...",
        });
        setTimeout(() => {
          instance.updateMessage({
            id: message.id,
            status: "succeed",
            content: "发送成功",
          });
        }, 2000);
      }
    },
    // éšè—å¯¼èˆªå¤´åƒ
    changeMenuAvatarVisible() {
      this.hideMenuAvatar = !this.hideMenuAvatar;
    },
    // éšè—å·¦ä¾§å¯¼èˆª
    changeMenuVisible() {
      this.hideMenu = !this.hideMenu;
    },
    // æ˜¯å¦éšè—èŠå¤©çª—口联系人名字
    changeMessageNameVisible() {
      this.hideMessageName = !this.hideMessageName;
    },
    // æ˜¯å¦éšè—èŠå¤©çª—口消息时间
    changeMessageTimeVisible() {
      this.hideMessageTime = !this.hideMessageTime;
    },
    removeMessage() {
      const { IMUI } = this.$refs;
      const messages = IMUI.getCurrentMessages();
      const id = messages[messages.length - 1].id;
      if (messages.length > 0) {
        IMUI.removeMessage(id);
      }
    },
    updateMessage() {
      const { IMUI } = this.$refs;
      const messages = IMUI.getCurrentMessages();
      const message = messages[messages.length - 1];
      if (messages.length > 0) {
        const update = {
          id: message.id,
          status: "succeed",
          type: "file",
          fileName: "被修改成文件了.txt",
          fileSize: "4200000",
        };
        if (message.type == "event") {
          update.fromUser = this.user;
        }
        IMUI.updateMessage(update);
        IMUI.messageViewToBottom();
      }
    },
    appendCustomMessage() {
      const { IMUI } = this.$refs;
      const message = {
        id: generateRandId(),
        status: "succeed",
        type: "voice",
        sendTime: getTime(),
        content: "语音消息",
        params1: "1",
        params2: "2",
        toContactId: "contact-1",
        fromUser: this.user,
      };
      IMUI.appendMessage(message, true);
    },
    appendMessage() {
      const { IMUI } = this.$refs;
      const contact = IMUI.currentContact;
      const message = generateMessage("contact-3");
      message.fromUser = {
        ...message.fromUser,
        ...this.user,
      };
      IMUI.appendMessage(message, true);
    },
    appendEventMessage() {
      const { IMUI } = this.$refs;
      const message = {
        id: generateRandId(),
        type: "event",
        content: (
          <span>
            é‚€è¯·ä½ åŠ å…¥ç¾¤èŠ{" "}
            <span
              style="color:#333;cursor:pointer"
              on-click={() => alert("OK")}
            >
              æŽ¥å—
            </span>
          </span>
        ),
        toContactId: "contact-3",
        sendTime: getTime(),
      };
      IMUI.appendMessage(message, true);
    },
    updateContact() {
      this.$refs.IMUI.updateContact({
        id: "contact-3",
        unread: 10,
        displayName: generateRandWord(),
        lastSendTime: getTime(),
        lastContent: "修改昵称为随机字母",
      });
    },
    changeDrawer(contact, instance) {
      instance.changeDrawer({
        //width: 240,
        //height: "90%",
        //offsetX:0 ,
        //offsetY: ,
        //position: "center",
        // inside: true,
        // offsetX: -280,
        // offsetY: -100,
        render: () => {
          return (
            <div class="drawer-content">
              <p>
                <b>自定义抽屉</b>
              </p>
              <p>{contact.displayName}</p>
            </div>
          );
        },
      });
    },
    // å·¦ä¾§è”系人点击触发
    handleChangeContact(contact, instance) {
      // åˆ‡æ¢æ—¶å…³é—­ws。因为有可能ws连接接收数据尚未完成,用户就跳转了页面
      this.requstWs();
      console.log("Event:change-contact");
      console.log(contact, instance);
      instance.updateContact({
        id: contact.id,
        unread: 0,
      });
      instance.closeDrawer();
    },
    // å»ºç«‹è¿žæŽ¥
    requstWs() {
      console.log("连接");
      // é˜²æ­¢ç”¨æˆ·å¤šæ¬¡è¿žç»­ç‚¹å‡»å‘起请求,所以要先关闭上次的ws请求。
      closeWebsocket();
      // è·ŸåŽç«¯åå•†ï¼Œéœ€è¦ä»€ä¹ˆå‚数数据给后台
      const obj = {
        type: "text",
        content: "帝得圣相相曰度",
        userId: "1", //接收数据方
      };
      // å‘èµ·ws请求
      sendWebsocket(
        "ws://192.168.1.4:8080/chat?userId=2",
        obj,
        this.wsMessage,
        this.wsError
      );
    },
    // æŽ¥æ”¶ws返回的数据
    wsMessage(data) {
      const dataJson = data;
      console.log(dataJson);
      const datas = {
        id: "唯一消息ID",
        status: "succeed",
        type: "text",
        sendTime: 1566047865417,
        content: "马上就对接完了!",
        toContactId: 2,
        fromUser: {
          //如果 id == this.user.id消息会显示在右侧,否则在左侧
          id: 2,
          displayName: "丽安娜",
          avatar: "",
        },
      };
      // IMUI.appendMessage(data);
    },
    //ws错误回调
    wsError(data) {
      console.log(data);
    },
    // å‘送新消息触发
    handleSend(message, next, file) {
      console.log(message, file);
      console.log(next);
      this.requstWs();
      setTimeout(() => {
        next();
      }, 1000);
    },
    // èŽ·å–è”ç³»äººä¿¡æ¯æˆ–æ»šåŠ¨åˆ°é¡¶éƒ¨è§¦å‘
    handlePullMessages(contact, next, instance) {
      console.log(contact, "获取联系人信息A");
      console.log(instance, "获取联系人信息B");
      console.log(next, "获取联系人信息C");
      const otheruser = {
        id: contact.id,
        displayName: contact.displayName,
        avatar: contact.avatar,
      };
      setTimeout(() => {
        const messages = [
          generateMessage(instance.currentContactId, this.user),
          generateMessage(instance.currentContactId, otheruser),
          generateMessage(instance.currentContactId, this.user),
          generateMessage(instance.currentContactId, otheruser),
          generateMessage(instance.currentContactId, this.user),
          generateMessage(instance.currentContactId, this.user),
          generateMessage(instance.currentContactId, otheruser),
          {
            ...generateMessage(instance.currentContactId, this.user),
            ...{ status: "failed" },
          },
        ];
        let isEnd = false;
        if (
          instance.getMessages(instance.currentContactId).length +
            messages.length >
          11
        )
          isEnd = true;
        next(messages, isEnd);
      }, 500);
    },
    // å·¦ä¾§å¯¼èˆªå¡åˆ‡æ¢æ—¶é—´
    handleChangeMenu() {
      console.log("Event:change-menu");
    },
    openCustomContainer() {},
  },
};
</script>
<style lang="scss" scoped>
scss ::selection {
  background: #000;
  color: #fff;
}
body {
  font-family: "Microsoft YaHei";
  background: #f6f6f6 !important;
}
#app {
  width: 90%;
  margin: 0 auto;
  padding-bottom: 100px;
  .scroll-top {
    cursor: pointer;
    position: fixed;
    bottom: 40px;
    left: 50%;
    border-radius: 50%;
    background: #fff;
    font-size: 18px;
    overflow: hidden;
    width: 40px;
    height: 40px;
    line-height: 40px;
    user-select: none;
    text-align: center;
    transform: rotate(-45deg) translateX(-50%);
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.1);
    &:hover {
      font-size: 22px;
    }
  }
  a {
    color: #0c5ed9;
    text-decoration: none;
    font-size: 12px;
  }
  .action {
    margin-top: 20px;
    .lemon-button {
      margin-right: 10px;
      margin-bottom: 10px;
    }
  }
  .link {
    font-size: 14px;
    margin-top: 15px;
    a {
      display: inline-block;
      margin: 0 5px;
      text-decoration: none;
      background: #ffba00;
      border-radius: 4px;
      padding: 5px 10px;
      color: rgba(0, 0, 0, 0.8);
    }
  }
  .logo {
    position: relative;
    display: inline-block;
    margin: 60px auto;
    user-select: none;
    .logo-text {
      font-size: 38px;
    }
    .logo-sub {
      font-size: 18px;
      color: #999;
      font-weight: 300;
    }
    .logo-badge {
      position: absolute;
      top: -10px;
      left: 230px;
      background: #000;
      border-radius: 16px;
      color: #f9f9f9;
      font-size: 12px;
      padding: 4px 8px;
    }
  }
  .title {
    font-size: 24px;
    line-height: 26px;
    border-left: 1px solid #ffba00;
    padding-left: 15px;
    margin-bottom: 15px;
    margin-top: 30px;
    user-select: none;
  }
  .table {
    width: 100%;
    border-radius: 10px;
    background: #fff;
    border-collapse: collapse;
    tr {
      cursor: pointer;
    }
    tr:not(.table-head):hover {
      background: #ffba00 !important;
    }
    tr:nth-of-type(even) {
      background: #f9f9f9;
    }
    th {
      user-select: none;
      color: #999;
    }
    td,
    th {
      text-align: left;
      padding: 10px 15px;
      font-size: 14px;
      font-weight: normal;
    }
  }
  .imui-center {
    margin-bottom: 60px;
    .lemon-wrapper {
      border: 1px solid #ddd;
    }
    .lemon-drawer {
      border: 1px solid #ddd;
      border-left: 0;
    }
  }
  .drawer-content {
    padding: 15px;
  }
  .more {
    font-size: 12px;
    line-height: 24px;
    height: 24px;
    position: absolute;
    top: 14px;
    right: 14px;
    cursor: pointer;
    user-select: none;
    color: #f1f1f1;
    display: inline-block;
    border-radius: 4px;
    background: #111;
    padding: 0 8px;
    &:active {
      background: #999;
    }
  }
  .bar {
    text-align: center;
    line-height: 30px;
    background: #fff;
    margin: 15px;
    color: #666;
    user-select: none;
    font-size: 12px;
  }
  .cover {
    text-align: center;
    user-select: none;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    i {
      font-size: 84px;
      color: #e6e6e6;
    }
    p {
      font-size: 18px;
      color: #ddd;
      line-height: 50px;
    }
  }
  .article-item {
    line-height: 34px;
    cursor: pointer;
    &:hover {
      text-decoration: underline;
      color: #318efd;
    }
  }
  pre {
    background: #fff;
    border-radius: 8px;
    padding: 15px;
  }
}
.lemon-simple .lemon-container {
  z-index: 5;
}
.lemon-simple .lemon-drawer {
  z-index: 4;
}
input#switch[type="checkbox"] {
  height: 0;
  width: 0;
  display: none;
}
label#switch-label {
  cursor: pointer;
  text-indent: -9999px;
  width: 34px;
  height: 20px;
  background: #aaa;
  display: block;
  border-radius: 100px;
  position: relative;
}
label#switch-label:after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: #fff;
  border-radius: 20px;
  transition: 0.3s;
}
input#switch:checked + label {
  background: #0fd547;
}
input#switch:checked + label:after {
  left: calc(100% - 2px);
  transform: translateX(-100%);
}
label#switch-label:active:after {
  width: 20px;
}
</style>
src/views/shortmessage/communication/lemon-message-voice.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
<script>
export default {
  name: "lemonMessageVoice",
  inheritAttrs: false,
  inject: ["IMUI"],
  render() {
    return (
      <lemon-message-basic
        class="lemon-message-voice"
        props={{ ...this.$attrs }}
        scopedSlots={{
          content: (props) => {
            return <span>{props.content}&nbsp;🔈</span>;
          },
        }}
      />
    );
  },
};
</script>
<style lang="scss" scoped>
.lemon-message.lemon-message-voice {
  user-select: none;
  .lemon-message__content {
    border: 2px solid #000;
    font-size: 12px;
    cursor: pointer;
    &::before {
      display: none;
    }
  }
}
</style>
src/views/shortmessage/healthinformation/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
<template>
  <div></div>
</template>
<script>
export default {
  data() {
    return {};
  },
  created() {},
  methods: {},
};
</script>
<style lang="scss" scoped></style>
src/views/shortmessage/messagebank/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,932 @@
<template>
  <div class="Questionnairemanagement">
    <!-- å·¦ä¾§æ  -->
    <div class="sidecolumn">
      <div class="notebuttom"><i class="el-icon-chat-dot-square" />发短信</div>
      <div class="notestate">
        <div class="state-text">短信状态</div>
        <div class="state-line">
          <div class="value-left">
            <i class="el-icon-chat-dot-square" />全部
          </div>
          <div class="quantityq">22</div>
        </div>
        <div class="state-line">
          <div class="value-left">
            <i class="el-icon-chat-dot-square" />发送成功
          </div>
          <div class="quantitycg">22</div>
        </div>
        <div class="state-line">
          <div class="value-left">
            <i class="el-icon-chat-dot-square" />发送失败
          </div>
          <div class="quantitysb">22</div>
        </div>
        <div class="state-line">
          <div class="value-left">
            <i class="el-icon-chat-dot-square" />待发送
          </div>
          <div class="quantityd">22</div>
        </div>
      </div>
    </div>
    <!-- å³ä¾§æ•°æ® -->
    <div class="leftvlue">
      <div class="leftvlue-top">短信详情</div>
      <div class="leftvlue-bg">
        <el-row :gutter="20">
          <!--用户数据-->
          <el-col :span="24" :xs="24">
            <el-form
              :model="queryParams"
              ref="queryForm"
              size="small"
              :inline="true"
              v-show="showSearch"
              label-width="98px"
            >
              <el-form-item label="手机号" prop="userName">
                <el-input
                  v-model="queryParams.userName"
                  placeholder="请输入"
                  clearable
                  style="width: 200px"
                  @keyup.enter.native="handleQuery"
                />
              </el-form-item>
              <el-form-item label="创建时间">
                <el-date-picker
                  v-model="dateRange"
                  style="width: 240px"
                  value-format="yyyy-MM-dd"
                  type="daterange"
                  range-separator="-"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                ></el-date-picker>
              </el-form-item>
              <el-form-item label="短信类型" prop="status">
                <el-select v-model="queryParams.status" placeholder="请选择">
                  <el-option
                    v-for="item in languagelist"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="操作用户" prop="status">
                <el-select v-model="queryParams.statusa" placeholder="请选择">
                  <el-option
                    v-for="item in qyoptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  icon="el-icon-search"
                  size="medium"
                  @click="handleQuery"
                  >搜索</el-button
                >
                <el-button
                  icon="el-icon-refresh"
                  size="medium"
                  @click="resetQuery"
                  >重置</el-button
                >
              </el-form-item>
            </el-form>
            <el-row :gutter="10" class="mb8">
              <el-col :span="1.5">
                <el-button
                  type="primary"
                  plain
                  icon="el-icon-plus"
                  size="medium"
                  @click="handleAdd"
                  v-hasPermi="['system:user:add']"
                  >新增</el-button
                >
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="danger"
                  plain
                  icon="el-icon-delete"
                  size="medium"
                  :disabled="multiple"
                  @click="handleDelete"
                  v-hasPermi="['system:user:remove']"
                  >删除</el-button
                >
              </el-col>
              <!-- <el-col :span="1.5"> </el-col> -->
            </el-row>
            <el-table
              v-loading="loading"
              :data="userList"
              :border="true"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="50" align="center" />
              <el-table-column
                label="序号"
                align="center"
                key="userId"
                prop="userId"
              />
              <el-table-column
                label="主旨"
                align="center"
                key="userName"
                prop="userName"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="问题文本"
                align="center"
                key="nickName"
                prop="nickName"
                width="400"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="问题语音"
                align="center"
                key="aphonenumber"
                prop="aphonenumber"
                width="400"
              /><el-table-column
                label="关联指标"
                align="center"
                key="bphonenumber"
                prop="bphonenumber"
                width="120"
              />
              <el-table-column
                label="指标选项"
                align="center"
                key="bphonenumber"
                prop="bphonenumber"
                width="120"
              />
              <el-table-column
                label="语言"
                align="center"
                key="indicator"
                prop="indicator"
                width="120"
              />
              <el-table-column label="是否启用" align="center" key="status">
                <template slot-scope="scope">
                  <el-switch
                    v-model="scope.row.status"
                    active-value="0"
                    inactive-value="1"
                    @change="handleStatusChange(scope.row)"
                  ></el-switch>
                </template>
              </el-table-column>
              <el-table-column
                label="操作"
                align="center"
                width="200"
                class-name="small-padding fixed-width"
              >
                <template slot-scope="scope">
                  <el-button
                    size="medium"
                    type="text"
                    @click="handleUpdate(scope.row)"
                    v-hasPermi="['system:user:edit']"
                    ><span class="button-textxg"
                      ><i class="el-icon-edit-outline"></i>修改</span
                    ></el-button
                  >
                  <el-button
                    size="medium"
                    type="text"
                    @click="compileUpdate(scope.row)"
                    v-hasPermi="['system:user:edit']"
                    ><span class="button-bji"
                      ><i class="el-icon-edit"></i>编辑短信</span
                    ></el-button
                  >
                  <el-button
                    size="medium"
                    type="text"
                    @click="handleDelete(scope.row)"
                    v-hasPermi="['system:user:remove']"
                    ><span class="button-textsc"
                      ><i class="el-icon-delete-solid"></i>删除</span
                    ></el-button
                  >
                </template>
              </el-table-column>
            </el-table>
            <pagination
              v-show="total > 0"
              :total="total"
              :page.sync="queryParams.pageNum"
              :limit.sync="queryParams.pageSize"
              @pagination="getList"
            />
          </el-col>
        </el-row>
        <!-- æ·»åŠ æˆ–ä¿®æ”¹çŸ­ä¿¡é…ç½®å¯¹è¯æ¡† -->
        <el-dialog
          :title="title"
          :visible.sync="indexopen"
          width="900px"
          append-to-body
        >
          <el-form
            ref="form"
            :model="indexform"
            :rules="rules"
            label-width="100px"
          >
            <el-row>
              <el-col :span="24">
                <el-form-item label="语言" prop="deptId">
                  <el-select
                    v-model="indexform.language"
                    placeholder="请选择语言"
                  >
                    <el-option
                      v-for="index in languagelist"
                      :key="index.value"
                      :label="index.label"
                      :value="index.value"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="短信主旨" prop="nickName">
                  <el-input
                    v-model="indexform.nickName"
                    placeholder="请输入短信主旨"
                    maxlength="80"
                  />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <div
                  style="display: flex; margin-left: 100px; margin-bottom: 10px"
                >
                  <div class="tsgname" @click="tsgnameto()">医院名称</div>
                  <div class="tsgname" @click="tsgnameto()">医院电话</div>
                  <div class="tsgname" @click="tsgnameto()">医院姓名</div>
                  <div class="tsgname" @click="tsgnameto()">随访姓名</div>
                  <div class="tsgname" @click="tsgnameto()">随访电话</div>
                  <div class="tsgname" @click="tsgnameto()">性别</div>
                  <div class="tsgname" @click="tsgnameto()">年龄</div>
                  <div class="tsgname" @click="tsgnameto()">地址</div>
                </div>
              </el-col></el-row
            >
            <el-row>
              <el-col :span="24">
                <el-form-item label="短信文本" prop="verbaltricktext">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="短信语音" prop="verbaltrickyy">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="无匹配文本" prop="matchtext">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="无匹配语音" prop="matchyy">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="无声文本" prop="silenttext">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="无声语音" prop="silentyy">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="通用库文本" prop="librarytext">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="通用库语音" prop="libraryy">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="听不清文本" prop="vaguetext">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="听不清语音" prop="vagueyy">
                  <el-input v-model="indexform.userName" maxlength="30" />
                </el-form-item> </el-col
            ></el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="短信规则" prop="email">
                  <el-input
                    v-model="indexform.remark"
                    type="textarea"
                    placeholder="请输入内容"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="是否启用">
                  <el-radio-group v-model="indexform.qystatus">
                    <el-radio
                      v-for="item in qyoptions"
                      :key="item.value"
                      :label="item.value"
                      >{{ item.label }}</el-radio
                    >
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="备注">
                  <el-input
                    v-model="indexform.remark"
                    type="textarea"
                    placeholder="请输入内容"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button type="primary" @click="submitForm">ç¡® å®š</el-button>
            <el-button @click="cancel">取 æ¶ˆ</el-button>
          </div>
        </el-dialog>
      </div>
    </div>
    <!-- æ·»åŠ ç±»åˆ«å¼¹æ¡† -->
    <el-dialog
      :title="amendtag ? '修改类别' : '新增类别'"
      width="30%"
      :visible.sync="dialogFormVisible"
    >
      <el-form :model="classifyform">
        <el-form-item
          :label="amendtag ? '请输入新的类别名称' : '请输入类别名称'"
        >
          <el-input
            v-model="classifyform.categoryname"
            autocomplete="off"
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitsidecolumn">ç¡® å®š</el-button>
      </div>
    </el-dialog>
    <!-- åˆ é™¤ç±»åˆ«ç¡®è®¤æ¡† -->
    <el-dialog title="警告" :visible.sync="deleteVisible" width="40%">
      <div style="font-size: 20px; color: rgb(247, 76, 76)">
        æ˜¯å¦ç¡®è®¤åˆ é™¤åˆ†ç±»ï¼š[<span>{{ deletefenl }}</span
        >]?
      </div>
      <div style="font-size: 20px">
        æ­¤æ“ä½œä¼šå°†è¯¥ç±»åˆ«ä¸‹æ‰€æœ‰æ¨¡å—转移至[未分类],是否继续删除此分类?
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="deleteVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="deletefenlei">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  listUser,
  getUser,
  delUser,
  addUser,
  updateUser,
} from "@/api/system/user";
import { getToken } from "@/utils/auth";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
  name: "questionnaire",
  dicts: ["sys_normal_disable", "sys_user_sex"],
  components: { Treeselect },
  data() {
    return {
      topactiveName: "Local", //顶部选择
      // é®ç½©å±‚
      loading: false,
      // é€‰ä¸­æ•°ç»„
      ids: [],
      // éžå•个禁用
      single: true,
      // éžå¤šä¸ªç¦ç”¨
      multiple: true,
      // æ˜¾ç¤ºæœç´¢æ¡ä»¶
      showSearch: true,
      // æ€»æ¡æ•°
      total: 0,
      namequestionnaire: "",
      haoquestionnaire: "",
      idds: "",
      amendtag: false, //是否修改类别
      dialogFormVisible: false, //修改添加类别弹框
      deleteVisible: false, //分类删除弹框
      deletefenl: "高血压", //删除项
      classifyform: {
        categoryname: "",
      }, //类别表单
      // è¡¨æ ¼æ•°æ®
      userList: [
        {
          userid: 1,
          userName: "血常规、尿常规",
          nickName: "贫血",
          aphonenumber: "(?!不.*|没.*|未.*)^.*([贫平凭血]|贫血|评学|评学),10",
          bphonenumber: "选择",
          cphonenumber: "普通话",
          status: "0",
        },
      ],
      // å¼¹å‡ºå±‚标题
      title: "",
      // æ˜¯å¦æ˜¾ç¤ºå¼¹å‡ºå±‚
      open: false,
      // æ—¥æœŸèŒƒå›´
      dateRange: [],
      // å²—位选项
      postOptions: [],
      // è§’色选项
      roleOptions: [],
      // æ·»åŠ ã€ä¿®æ”¹å‚æ•°
      indexform: {},
      numberlb: 22,
      numberlbs: 2,
      sidecolumnform: {}, //添加类别表单
      dialogFormVisible: false, //添加类别弹框
      sidecolumnval: "", //类别搜索
      indexopen: false, //弹框展示否
      propss: { multiple: true },
      languagelist: [
        {
          value: 1,
          label: "全部",
        },
        {
          value: 2,
          label: "出院病情随访",
        },
        {
          value: 3,
          label: "语音随访后短信",
        },
        {
          value: 4,
          label: "医生随访后短信",
        },
      ], //语言列表
      qyoptions: [
        {
          value: 1,
          label: "启用",
        },
        {
          value: 2,
          label: "关闭",
        },
      ],
      //类别列表
      editableTabs: [
        {
          title: "短信分类一",
          number: "1",
        },
        {
          title: "短信分类二",
          number: "2",
        },
        {
          title: "短信分类三",
          number: "2",
        },
        {
          title: "短信分类四",
          number: "2",
        },
        {
          title: "短信分类五",
          number: "2",
        },
      ],
      // æŸ¥è¯¢å‚æ•°
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        userName: undefined,
        phonenumber: undefined,
        status: undefined,
        deptId: undefined,
        IDnumber: undefined,
      },
      // è¡¨å•校验
      rules: {
        userName: [
          { required: true, message: "主旨不能为空", trigger: "blur" },
          {
            min: 2,
            max: 20,
            message: "用户名称长度必须介于 2 å’Œ 20 ä¹‹é—´",
            trigger: "blur",
          },
        ],
        nickName: [
          { required: true, message: "用户昵称不能为空", trigger: "blur" },
        ],
        password: [
          { required: true, message: "用户密码不能为空", trigger: "blur" },
          {
            min: 5,
            max: 20,
            message: "用户密码长度必须介于 5 å’Œ 20 ä¹‹é—´",
            trigger: "blur",
          },
        ],
        email: [
          {
            type: "email",
            message: "请输入正确的邮箱地址",
            trigger: ["blur", "change"],
          },
        ],
        phonenumber: [
          {
            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
            message: "请输入正确的手机号码",
            trigger: "blur",
          },
        ],
        IDnumber: [
          {
            pattern:
              /^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))(\d|X|x)$/,
            message: "请输入正确的身份证号码",
            trigger: "blur",
          },
        ],
      },
    };
  },
  watch: {},
  created() {
    this.getList();
  },
  methods: {
    /** æŸ¥è¯¢ç”¨æˆ·åˆ—表 */
    getList() {
      //   this.loading = true;
      listUser().then((response) => {
        console.log(response);
        console.log(this.userList);
      });
    },
    // æ·»åŠ ã€ä¿®æ”¹ç±»åˆ«
    submitsidecolumn() {
      if (this.amendtag) {
        this.classifyform.tagcategoryid = this.idds;
        // toamendtagcategory(this.addDateRange(this.classifyform)).then(
        //   (response) => {
        //     console.log(response);
        //     this.gitclasify();
        //   }
        // );
      } else {
        // addtagcategory(this.addDateRange(this.classifyform)).then(
        //   (response) => {
        //     console.log(response);
        //     this.gitclasify();
        //   }
        // );
      }
      this.classifyform = {
        categoryname: "",
      };
      this.idds = "";
      this.dialogFormVisible = false;
    },
    //删除分类
    deletefenlei(row) {
      if (this.deleteVisible) {
        // deletetagcategory(this.idds).then((response) => {
        //   console.log(response);
        //   this.gitclasify();
        // });
        this.deleteVisible = false;
        this.idds = "";
      } else {
        this.deleteVisible = true;
        this.idds = row.tagcategoryid;
        this.deletefenl = row.title;
      }
    },
    compileUpdate(row) {
      this.$router.push({
        path: "/repositoryai/verbaltrick/particulars/",
        query: { id: "1" },
      });
    },
    // é¢˜ç›®çŠ¶æ€ä¿®æ”¹
    handleStatusChange(row) {
      let text = row.status === "0" ? "启用" : "停用";
      this.$modal
        .confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
        .then(function () {
          return changeUserStatus(row.userId, row.status);
        })
        .then(() => {
          this.$modal.msgSuccess(text + "成功");
        })
        .catch(function () {
          row.status = row.status === "0" ? "1" : "0";
        });
    },
    //搜索类别
    sidecolumnss() {},
    // ä¾¿æ·æ ‡ç­¾
    tsgnameto() {},
    // åˆ‡æ¢å…±äº«/本地
    tophandleClick() {},
    // å–消按钮
    cancel() {
      this.indexopen = false;
      this.reset();
    },
    // è¡¨å•重置
    reset() {
      this.form = {
        userId: undefined,
        deptId: undefined,
        userName: undefined,
        nickName: undefined,
        password: undefined,
        phonenumber: undefined,
        email: undefined,
        sex: undefined,
        status: "0",
        remark: undefined,
        postIds: [],
        roleIds: [],
      };
      this.resetForm("form");
    },
    /** æœç´¢æŒ‰é’®æ“ä½œ */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** é‡ç½®æŒ‰é’®æ“ä½œ */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.queryParams.deptId = undefined;
      this.$refs.tree.setCurrentKey(null);
      this.handleQuery();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.userId);
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    /** æ–°å¢žæŒ‰é’®æ“ä½œ */
    handleAdd() {
      this.reset();
      this.title = "新增短信";
      this.indexopen = true;
    },
    /** ä¿®æ”¹æŒ‰é’®æ“ä½œ */
    handleUpdate(row) {
      this.reset();
      this.title = "修改短信";
      this.indexopen = true;
    },
    // ä¿®æ”¹åˆ†ç±»å¼¹æ¡†
    popoveramend(tagcategoryid) {
      this.idds = tagcategoryid;
      this.amendtag = true;
      this.dialogFormVisible = true;
    },
    /** æ›´æ–°/修改提交按钮 */
    submitForm: function () {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.form.userId != undefined) {
            updateUser(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.indexopen = false;
              this.getList();
            });
          } else {
            addUser(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.indexopen = false;
              this.getList();
            });
          }
        }
      });
    },
    /** åˆ é™¤æŒ‰é’®æ“ä½œ */
    handleDelete(row) {
      const userIds = row.userId || this.ids;
      this.$modal
        .confirm('是否确认删除用户编号为"' + userIds + '"的数据项?')
        .then(function () {
          return delUser(userIds);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
  },
};
</script>
<style lang="scss" scoped>
.Questionnairemanagement {
  display: flex;
}
.sidecolumn {
  width: 300px;
  min-height: 100vh;
  text-align: center;
  //   display: flex;
  margin-top: 20px;
  margin: 20px;
  padding: 30px;
  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);
  .sidecolumn-top {
    display: flex;
    justify-content: space-between;
    .top-wj {
      font-size: 20px;
    }
    .top-tj {
      font-size: 18px;
      color: rgb(0, 89, 255);
      cursor: pointer;
    }
  }
  .center-ss {
    margin-top: 30px;
    .input-with-select {
      height: 40px !important;
    }
  }
  .bottom-fl {
    margin-top: 30px;
    display: center !important;
  }
}
.qrcode-dialo {
  text-align: center;
  //   display: flex;
  margin: 20px;
  padding: 30px;
  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);
  .qrcode-text {
    font-size: 20px;
    span {
      margin-left: 20px;
    }
  }
  .qrcode-img {
    width: 300px;
    height: 400px;
  }
}
.tsgname {
  width: 90px;
  margin-right: 10px;
  text-align: center;
  cursor: pointer;
  height: 40px;
  line-height: 40px;
  background: #7799fa;
  color: #ffff;
  font-size: 18px;
  border-radius: 5px;
}
.tsgname:hover {
  background: #3366f5;
}
::v-deep.el-tabs--left,
.el-tabs--right {
  overflow: hidden;
  align-items: center;
  display: flex;
}
::v-deep.el-input--medium .el-input__inner {
  height: 40px !important;
}
::v-deep.el-tabs--right .el-tabs__active-bar.is-right {
  height: 40px;
  width: 5px;
  left: 0;
}
::v-deep.el-tabs--right .el-tabs__item.is-right {
  display: block;
  font-size: 20px;
}
.leftvlue {
  //   display: flex;
  //   flex: 1;
  width: 80%;
  margin-top: 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);
  .mulsz {
    font-size: 20px;
  }
}
.button-text {
  color: rgb(70, 204, 238);
}
.button-bji {
  color: rgb(39, 167, 67);
}
.button-textxg {
  color: rgb(35, 81, 233);
}
.button-textsc {
  color: rgb(235, 23, 23);
}
</style>
src/views/shortmessage/taglibrary/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,711 @@
<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!--用户数据-->
      <el-col :span="24" :xs="24">
        <el-form
          :model="topqueryParams"
          ref="queryForm"
          size="small"
          :inline="true"
          v-show="showSearch"
          label-width="98px"
        >
          <el-form-item label="标签名称" prop="userName">
            <el-input
              v-model="topqueryParams.userName"
              placeholder="请输入"
              clearable
              style="width: 200px"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              icon="el-icon-search"
              size="medium"
              @click="handleQuery"
              >搜索</el-button
            >
            <el-button icon="el-icon-refresh" size="medium" @click="resetQuery"
              >重置</el-button
            >
          </el-form-item>
        </el-form>
        <el-divider></el-divider>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              size="medium"
              @click="handleAdd"
              v-hasPermi="['system:user:add']"
              >新增</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="success"
              plain
              icon="el-icon-edit"
              size="medium"
              :disabled="single"
              @click="handleUpdate"
              v-hasPermi="['system:user:edit']"
              >修改</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="danger"
              plain
              icon="el-icon-delete"
              size="medium"
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['system:user:remove']"
              >删除</el-button
            >
          </el-col>
          <el-col :span="19">
            <div class="documentf">
              <div class="document">
                <el-button
                  type="warning"
                  plain
                  icon="el-icon-download"
                  size="medium"
                  @click="handleExport"
                  v-hasPermi="['system:user:export']"
                  >导出</el-button
                >
              </div>
            </div>
          </el-col>
          <!-- <el-col :span="1.5"> </el-col> -->
        </el-row>
        <!-- <right-toolbar
              :showSearch.sync="showSearch"
              @queryTable="getList"
              :columns="columns"
            ></right-toolbar> -->
        <el-table
          v-loading="loading"
          :data="userList"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column
            label="序号"
            align="center"
            key="userId"
            prop="userId"
          />
          <el-table-column
            label="标签名称"
            align="center"
            key="userName"
            prop="userName"
            :show-overflow-tooltip="true"
          />
          <el-table-column
            label="账号"
            align="center"
            key="types"
            prop="types"
          />
          <el-table-column
            label="密码"
            align="center"
            key="nickName"
            prop="nickName"
          />
          <el-table-column
            label="备注"
            align="center"
            key="phonenumber"
            prop="phonenumber"
            width="120"
          />
          <el-table-column label="是否启用" align="center" key="status">
            <template slot-scope="scope">
              <el-switch
                v-model="scope.row.status"
                active-value="0"
                inactive-value="1"
                @change="handleStatusChange(scope.row)"
              ></el-switch>
            </template>
          </el-table-column>
          <el-table-column
            label="最近更新日期"
            align="center"
            prop="createTime"
            width="160"
          >
            <template slot-scope="scope">
              <span>{{ parseTime(scope.row.createTime) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            align="center"
            width="160"
            class-name="small-padding fixed-width"
          >
            <template slot-scope="scope">
              <el-button
                size="medium"
                type="text"
                icon="el-icon-edit"
                @click="handleUpdate(scope.row)"
                v-hasPermi="['system:user:edit']"
                >编辑</el-button
              >
              <el-button
                size="medium"
                type="text"
                @click="handleDelete(scope.row)"
                ><span style="color: rgb(236, 55, 55)"
                  ><i class="el-icon-delete-solid"></i>删除</span
                ></el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <pagination
          v-show="total > 0"
          :total="total"
          :page.sync="topqueryParams.pageNum"
          :limit.sync="topqueryParams.pageSize"
          @pagination="getList"
        />
      </el-col>
    </el-row>
    <!-- æ·»åŠ æˆ–ä¿®æ”¹æ ‡ç­¾é…ç½®å¯¹è¯æ¡† -->
    <el-dialog
      :title="title"
      :visible.sync="addalteropen"
      width="900px"
      append-to-body
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="标签名称" prop="nickName">
              <el-input
                v-model="form.nickName"
                placeholder="请输入"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="短信平台账号" prop="email">
              <el-input
                v-model="form.nickName"
                placeholder="请输入"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="短信平台密码" prop="email">
              <el-input
                v-model="form.nickName"
                placeholder="请输入"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="是否启用">
              <el-radio-group v-model="form.qystatus">
                <el-radio
                  v-for="item in qyoptions"
                  :key="item.value"
                  :label="item.value"
                  >{{ item.label }}</el-radio
                >
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input
                v-model="form.remark"
                type="textarea"
                placeholder="请输入内容"
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">ç¡® å®š</el-button>
        <el-button @click="cancel">取 æ¶ˆ</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  listUser,
  getUser,
  delUser,
  addUser,
  updateUser,
  resetUserPwd,
  changeUserStatus,
} from "@/api/system/user";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
  name: "User",
  dicts: ["sys_normal_disable", "sys_user_sex"],
  components: { Treeselect },
  data() {
    return {
      // é®ç½©å±‚
      loading: true,
      // é€‰ä¸­æ•°ç»„
      ids: [],
      // éžå•个禁用
      single: true,
      // éžå¤šä¸ªç¦ç”¨
      multiple: true,
      // æ˜¾ç¤ºæœç´¢æ¡ä»¶
      showSearch: true,
      // æ€»æ¡æ•°
      total: 0,
      // ç”¨æˆ·è¡¨æ ¼æ•°æ®
      userList: null,
      // å¼¹å‡ºå±‚标题
      title: "",
      // æ˜¯å¦æ˜¾ç¤ºä¿®æ”¹ã€æ·»åŠ å¼¹å‡ºå±‚
      addalteropen: false,
      // éƒ¨é—¨åç§°
      deptName: undefined,
      // é»˜è®¤å¯†ç 
      initPassword: undefined,
      // æ—¥æœŸèŒƒå›´
      dateRange: [],
      // å²—位选项
      postOptions: [],
      // è§’色选项
      roleOptions: [],
      dynamicTags: ["选项一", "选项二", "选项三"], //选项
      inputVisible: false,
      inputValue: "",
      previewVisible: false, //标签预览弹框
      radio: "",
      radios: [],
      previewtype: 2, //预览标签类型
      total: 0, // æ€»æ¡æ•°
      ImportQuantity: 999, //导标签数量
      //预览标签信息
      previewvalue: {
        username: "这个医生对你怎么样",
      },
      // è¡¨å•参数
      form: {
        phonenumber: "",
        totagid: "",
        types: "",
        nickName: "",
        qystatus: "",
        btstatus: "",
      },
      // æŸ¥è¯¢å‚æ•°
      topqueryParams: {
        pageNum: 1,
      },
      propss: { multiple: true },
      optionss: [
        {
          value: 1,
          label: "东南",
        },
        {
          value: 2,
          label: "西北",
        },
        {
          value: 3,
          label: "仨仨仨",
        },
        {
          value: 4,
          label: "六飒飒飒",
        },
      ],
      qyoptions: [
        {
          value: 1,
          label: "启用",
        },
        {
          value: 2,
          label: "关闭",
        },
      ],
      btoptions: [
        {
          value: 1,
          label: "必填",
        },
        {
          value: 2,
          label: "非必填",
        },
      ],
      topicoptions: [
        {
          value: 1,
          label: "单选",
        },
        {
          value: 2,
          label: "多选",
        },
        {
          value: 3,
          label: "填空",
        },
      ],
      // è¡¨å•校验
      rules: {
        userName: [
          { required: true, message: "用户名称不能为空", trigger: "blur" },
          {
            min: 2,
            max: 20,
            message: "用户名称长度必须介于 2 å’Œ 20 ä¹‹é—´",
            trigger: "blur",
          },
        ],
        nickName: [
          { required: true, message: "用户昵称不能为空", trigger: "blur" },
        ],
        password: [
          { required: true, message: "用户密码不能为空", trigger: "blur" },
          {
            min: 5,
            max: 20,
            message: "用户密码长度必须介于 5 å’Œ 20 ä¹‹é—´",
            trigger: "blur",
          },
        ],
        email: [
          {
            type: "email",
            message: "请输入正确的邮箱地址",
            trigger: ["blur", "change"],
          },
        ],
        phonenumber: [
          {
            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
            message: "请输入正确的手机号码",
            trigger: "blur",
          },
        ],
        IDnumber: [
          {
            pattern:
              /^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))(\d|X|x)$/,
            message: "请输入正确的身份证号码",
            trigger: "blur",
          },
        ],
      },
    };
  },
  watch: {},
  created() {
    this.getList();
    this.getConfigKey("sys.user.initPassword").then((response) => {
      this.initPassword = response.msg;
    });
  },
  methods: {
    /** æŸ¥è¯¢æ ‡ç­¾åˆ—表 */
    getList() {
      this.loading = true;
      listUser(this.addDateRange(this.topqueryParams, this.dateRange)).then(
        (response) => {
          this.userList = response.rows;
          this.total = response.total;
          this.loading = false;
        }
      );
    },
    // æ ‡ç­¾çŠ¶æ€ä¿®æ”¹
    handleStatusChange(row) {
      let text = row.status === "0" ? "启用" : "停用";
      this.$modal
        .confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
        .then(function () {
          return changeUserStatus(row.userId, row.status);
        })
        .then(() => {
          this.$modal.msgSuccess(text + "成功");
        })
        .catch(function () {
          row.status = row.status === "0" ? "1" : "0";
        });
    },
    // å–消按钮
    cancel() {
      this.addalteropen = false;
      this.reset();
    },
    // è¡¨å•重置
    reset() {
      this.form = {
        userId: undefined,
        deptId: undefined,
        userName: undefined,
        nickName: undefined,
        password: undefined,
        phonenumber: undefined,
        email: undefined,
        sex: undefined,
        status: "0",
        remark: undefined,
        postIds: [],
        roleIds: [],
      };
      this.resetForm("form");
    },
    /** æœç´¢æŒ‰é’®æ“ä½œ */
    handleQuery() {
      this.topqueryParams.pageNum = 1;
      this.getList();
    },
    /** é‡ç½®æŒ‰é’®æ“ä½œ */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.topqueryParams.deptId = undefined;
      this.$refs.tree.setCurrentKey(null);
      this.handleQuery();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.userId);
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    //删除选项
    handleClose(tag) {
      this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
    },
    //触发新增输入
    showInput() {
      this.inputVisible = true;
      this.$nextTick((_) => {
        this.$refs.saveTagInput.$refs.input.focus();
      });
    },
    //获取失去焦点触发
    handleInputConfirm() {
      let inputValue = this.inputValue;
      if (inputValue) {
        this.dynamicTags.push(inputValue);
      }
      this.inputVisible = false;
      this.inputValue = "";
    },
    /** æ–°å¢žæŒ‰é’®æ“ä½œ */
    handleAdd() {
      this.reset();
      this.title = "新增标签";
      this.addalteropen = true;
    },
    /** ä¿®æ”¹æŒ‰é’®æ“ä½œ */
    handleUpdate(row) {
      this.reset();
      this.title = "修改标签";
      this.addalteropen = true;
      //   const userId = row.userId || this.ids;
      //   getUser(userId).then((response) => {
      //     this.form = response.data;
      //     this.postOptions = response.posts;
      //     this.roleOptions = response.roles;
      //     this.$set(this.form, "postIds", response.postIds);
      //     this.$set(this.form, "roleIds", response.roleIds);
      //     this.addalteropen = true;
      //     this.form.password = "";
      //   });
    },
    /** é‡ç½®å¯†ç æŒ‰é’®æ“ä½œ */
    handleResetPwd(row) {
      this.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        closeOnClickModal: false,
        inputPattern: /^.{5,20}$/,
        inputErrorMessage: "用户密码长度必须介于 5 å’Œ 20 ä¹‹é—´",
      })
        .then(({ value }) => {
          resetUserPwd(row.userId, value).then((response) => {
            this.$modal.msgSuccess("修改成功,新密码是:" + value);
          });
        })
        .catch(() => {});
    },
    /** æäº¤æŒ‰é’® */
    submitForm: function () {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.form.userId != undefined) {
            updateUser(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addUser(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** åˆ é™¤æŒ‰é’®æ“ä½œ */
    handleDelete(row) {
      const userIds = row.userId || this.ids;
      this.$modal
        .confirm('是否确认删除用户编号为"' + userIds + '"的数据项?')
        .then(function () {
          return delUser(userIds);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
      this.download(
        "system/user/export",
        {
          ...this.topqueryParams,
        },
        `user_${new Date().getTime()}.xlsx`
      );
    },
  },
};
</script>
<style lang="scss" scoped>
.el-button--primary.is-plain {
  color: #ffffff;
  background: #409eff;
  border-color: #4fabe9;
}
.document {
  width: 100px;
  height: 50px;
}
.documentf {
  display: flex;
  justify-content: flex-end;
}
.download {
  text-align: center;
  .el-upload__tip {
    font-size: 23px;
  }
  .el-upload__text {
    font-size: 23px;
  }
}
.uploading {
  margin-top: 20px;
  margin: 20px;
  padding: 30px;
  background: #ffffff;
  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);
}
.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;
}
.drexamine {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30px;
  background: #daeaf5;
  img {
    width: 100px;
    height: 100px;
  }
}
.qrcode-dialo {
  // text-align: center;
  //   display: flex;
  margin: 20px;
  padding: 30px;
  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);
  .topic-dev {
    margin-bottom: 25px;
    font-size: 20px !important;
    .dev-text {
      margin-bottom: 10px;
    }
  }
}
::v-deep.el-radio-group {
  span {
    font-size: 24px;
  }
}
::v-deep.el-checkbox-group {
  span {
    font-size: 24px;
  }
}
</style>
src/websocket/websocket.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
import { Message } from 'element-ui'
// import { getToken } from '@/utils/authToken' // ä¸ŽåŽç«¯çš„协商,websocket请求需要带上token参数
let websock = null
let messageCallback = null
let errorCallback = null
let wsUrl = ''
let tryTime = 0
// æŽ¥æ”¶ws后端返回的数据
function websocketonmessage (e) {
    console.log(e);
  messageCallback(JSON.stringify(e.data))
}
/**
 * å‘èµ·websocket连接
 * @param {Object} agentData éœ€è¦å‘后台传递的参数数据
 */
function websocketSend (agentData) {
  // åŠ å»¶è¿Ÿæ˜¯ä¸ºäº†å°½é‡è®©ws连接状态变为OPEN
  setTimeout(() => {
    // æ·»åŠ çŠ¶æ€åˆ¤æ–­ï¼Œå½“ä¸ºOPEN时,发送消息
    if (websock.readyState === websock.OPEN) { // websock.OPEN = 1
      // å‘给后端的数据需要字符串化
      websock.send(JSON.stringify(agentData))
      console.log('连接成功');
    }
    if (websock.readyState === websock.CLOSED) { // websock.CLOSED = 3
      console.log('websock.readyState=3')
      Message.error('ws连接异常,请稍候重试c')
      errorCallback()
    }
  }, 500)
}
// å…³é—­ws连接
function websocketclose (e) {
  // e.code === 1000  è¡¨ç¤ºæ­£å¸¸å…³é—­ã€‚ æ— è®ºä¸ºä½•目的而创建, è¯¥é“¾æŽ¥éƒ½å·²æˆåŠŸå®Œæˆä»»åŠ¡ã€‚
  // e.code !== 1000  è¡¨ç¤ºéžæ­£å¸¸å…³é—­ã€‚
  if (e && e.code !== 1000) {
    Message.error('ws连接异常,请稍候重试b')
    errorCallback()
    // // å¦‚果需要设置异常重连则可替换为下面的代码,自行进行测试
    // if (tryTime < 10) {
    //   setTimeout(function() {
    //    websock = null
    //    tryTime++
    //    initWebSocket()
    //    console.log(`第${tryTime}次重连`)
    //  }, 3 * 1000)
    //} else {
    //  Message.error('重连失败!请稍后重试')
    //}
  }
}
// å»ºç«‹ws连接
function websocketOpen (e) {
  // console.log('ws连接成功')
}
// åˆå§‹åŒ–weosocket
function initWebSocket () {
  if (typeof (WebSocket) === 'undefined') {
    Message.error('您的浏览器不支持WebSocket,无法获取数据')
    return false
  }
//   const token = 'JWT=' + getToken()
  // ws请求完整地址
//   const requstWsUrl = wsUrl + '?' + token
  const requstWsUrl = wsUrl
  websock = new WebSocket(requstWsUrl)
  websock.onmessage = function (e) {
    websocketonmessage(e)
  }
  websock.onopen = function () {
    websocketOpen()
  }
  websock.onerror = function () {
    Message.error('ws连接异常,请稍候重试a')
    errorCallback()
  }
  websock.onclose = function (e) {
    // websocketclose(e)
  }
}
/**
 * å‘èµ·websocket请求函数
 * @param {string} url ws连接地址
 * @param {Object} agentData ä¼ ç»™åŽå°çš„参数
 * @param {function} successCallback æŽ¥æ”¶åˆ°ws数据,对数据进行处理的回调函数
 * @param {function} errCallback ws连接错误的回调函数
 */
export function sendWebsocket (url, agentData, successCallback, errCallback) {
  wsUrl = url
  initWebSocket()
  messageCallback = successCallback
  errorCallback = errCallback
  websocketSend(agentData)
}
/**
 * å…³é—­websocket函数
 */
export function closeWebsocket () {
  if (websock) {
    websock.close() // å…³é—­websocket
    websock.onclose() // å…³é—­websocket
  }
}