智慧保安考试系统
zhongrj
2023-06-25 545522da7622f5623731d7ab257bcf442cd9d5ec
晋城保安版本
11 files modified
1 files added
8935 ■■■■■ changed files
README.md 44 ●●●●● patch | view | raw | blame | history
package-lock.json 8522 ●●●●● patch | view | raw | blame | history
package.json 4 ●●●● patch | view | raw | blame | history
src/page/login/userlogin.vue 4 ●●●● patch | view | raw | blame | history
src/router/axios copy.js 80 ●●●●● patch | view | raw | blame | history
src/views/applyexam/index.vue 2 ●●● patch | view | raw | blame | history
src/views/exam/examSubjects.vue 4 ●●●● patch | view | raw | blame | history
src/views/exam/examination.vue 2 ●●● patch | view | raw | blame | history
src/views/exam/performance.vue 2 ●●● patch | view | raw | blame | history
src/views/exam/startexam.vue 78 ●●●●● patch | view | raw | blame | history
src/views/startexam/index.vue 189 ●●●●● patch | view | raw | blame | history
vue.config.js 4 ●●●● patch | view | raw | blame | history
README.md
@@ -1,43 +1 @@
## 版权声明
* BladeX是一个商业化软件,系列产品知识产权归**上海布雷德网络科技**独立所有
* 您一旦开始复制、下载、安装或者使用本产品,即被视为完全理解并接受本协议的各项条款
* 更多详情请看:[BladeX商业授权许可协议](/LICENSE)
## 答疑流程
>1. 遇到问题或Bug
>2. 业务型问题打断点调试尝试找出问题所在
>3. 系统型问题通过百度、谷歌、社区查找解决方案
>4. 未解决问题则进入技术社区进行发帖提问:[https://sns.bladex.vip/](https://sns.bladex.vip/)
>5. 将帖子地址发至商业群,特别简单三言两语就能描述清楚的也可在答疑时间内发至商业群提问
>6. 发帖的时候一定要描述清楚,详细描述遇到问题的**重现步骤**、**报错详细信息**、**相关代码与逻辑**、**使用软件版本**以及**操作系统版本**,否则随意发帖提问将会提高我们的答疑难度。
## 答疑时间
* 工作日:9:00 ~ 17:00 提供答疑,周末、节假日休息,暂停答疑
* 请勿**私聊提问**,以免被其他用户的消息覆盖从而无法获得答疑
* 答疑时间外遇到问题可以将问题发帖至[技术社区](https://sns.bladex.vip/),我们后续会逐个回复
## 授权范围
* 专业版:只可用于**个人学习**及**个人私活**项目,不可用于公司或团队,不可泄露给任何第三方
* 企业版:可用于**企业名下**的任何项目,企业版员工在**未购买**专业版授权前,只授权开发**所在授权企业名下**的项目,**不得将BladeX用于个人私活**
* 共同遵守:若甲方需要您提供项目源码,则需代为甲方购买BladeX企业授权,甲方购买后续的所有项目都无需再次购买授权
## 商用权益
* ✔️ 遵守[商业协议](/LICENSE)的前提下,将BladeX系列产品用于授权范围内的商用项目,并上线运营
* ✔️ 遵守[商业协议](/LICENSE)的前提下,不限制项目数,不限制服务器数
* ✔️ 遵守[商业协议](/LICENSE)的前提下,将自行编写的业务代码申请软件著作权
## 何为侵权
* ❌ 不遵守商业协议,私自销售商业源码
* ❌ 以任何理由将BladeX源码用于申请软件著作权
* ❌ 将商业源码以任何途径任何理由泄露给未授权的单位或个人
* ❌ 开发完毕项目,没有为甲方购买企业授权,向甲方提供了BladeX代码
* ❌ 基于BladeX拓展研发与BladeX有竞争关系的衍生框架,并将其开源或销售
## 侵权后果
* 情节较轻:第一次发现警告处理
* 情节较重:封禁账号,踢出商业群,并保留追究法律责任的权利
* 情节严重:与本地律师事务所合作,以公司名义起诉侵犯计算机软件著作权
## 举报有奖
* 向官方提供有用线索并成功捣毁盗版个人或窝点,将会看成果给予 500~10000 不等的现金奖励
* 官方唯一指定QQ:1272154962
# 注意node和 Node-sass  版本对应问题,应为 14 版本
package-lock.json
Diff too large
package.json
@@ -39,8 +39,8 @@
    "@vue/cli-plugin-eslint": "^3.1.5",
    "@vue/cli-service": "^3.1.4",
    "chai": "^4.1.2",
    "node-sass": "^4.12.0",
    "sass-loader": "^7.0.1",
    "node-sass": "^4.14.1",
    "sass-loader": "^7.3.1",
    "vue-template-compiler": "^2.5.17",
    "webpack-bundle-analyzer": "^3.0.3"
  },
src/page/login/userlogin.vue
@@ -25,7 +25,7 @@
          @keyup.enter.native="handleLogin"
          v-model="loginForm.username"
          auto-complete="off"
          placeholder="请输入账号"
          placeholder="请输入身份证号码"
        >
          <i slot="prefix" class="icon-yonghu" />
        </el-input>
@@ -118,7 +118,7 @@
          { required: false, message: "请输入租户ID", trigger: "blur" },
        ],
        username: [
          { required: true, message: "请输入账号", trigger: "blur" },
          { required: true, message: "请输入身份证号码", trigger: "blur" },
        ],
        password: [
          {
src/router/axios copy.js
New file
@@ -0,0 +1,80 @@
/**
 * 全站http配置
 *
 * axios参数说明
 * isSerialize是否开启form表单提交
 * isToken是否需要token
 */
import axios from 'axios';
import store from '@/store/';
import router from '@/router/router';
import {serialize} from '@/util/util';
import {getToken} from '@/util/auth';
import {Message} from 'element-ui';
import website from '@/config/website';
import {Base64} from 'js-base64';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
//默认超时时间
axios.defaults.timeout = 10000;
//返回其他状态码
axios.defaults.validateStatus = function (status) {
  return status >= 200 && status <= 500;
};
//跨域请求,允许保存cookie
axios.defaults.withCredentials = true;
// NProgress 配置
NProgress.configure({
  showSpinner: false
});
//http request拦截
axios.interceptors.request.use(config => {
  //开启 progress bar
  NProgress.start();
  const meta = (config.meta || {});
  const isToken = meta.isToken === false;
  config.headers['Authorization'] = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`;
  //让每个请求携带token
  if (getToken() && !isToken) {
    config.headers[website.tokenHeader] = 'bearer ' + getToken()
  }
  //headers中配置text请求
  if (config.text === true) {
    config.headers["Content-Type"] = "text/plain";
  }
  //headers中配置serialize为true开启序列化
  if (config.method === 'post' && meta.isSerialize === true) {
    config.data = serialize(config.data);
  }
  return config
}, error => {
  return Promise.reject(error)
});
//http response 拦截
axios.interceptors.response.use(res => {
  //关闭 progress bar
  NProgress.done();
  //获取状态码
  const status = res.data.code || res.status;
  const statusWhiteList = website.statusWhiteList || [];
  const message = res.data.msg || res.data.error_description || '未知错误';
  //如果在白名单里则自行catch逻辑处理
  if (statusWhiteList.includes(status)) return Promise.reject(res);
  //如果是401则跳转到登录页面
  if (status === 401) store.dispatch('FedLogOut').then(() => router.push({path: '/login'}));
  // 如果请求为非200否者默认统一处理
  if (status !== 200) {
    Message({
      message: message,
      type: 'error'
    });
    return Promise.reject(new Error(message))
  }
  return res;
}, error => {
  NProgress.done();
  return Promise.reject(new Error(error));
});
export default axios;
src/views/applyexam/index.vue
@@ -334,7 +334,7 @@
    },
    created () {
      console.log(this.userInfo)
    //   console.log(this.userInfo)
      if (this.userInfo.role_name.indexOf('ksxtadmin') != -1) {
src/views/exam/examSubjects.vue
@@ -88,7 +88,7 @@
    data () {
        var validatePass = (rule, value, callback) => {
            console.log(value)
            // console.log(value)
            if (value == undefined || value == '') {
                callback(new Error('请输入分数'));
                return;
@@ -291,7 +291,7 @@
        },
        questionBankRowSave (row, done, loading) {
            console.log(row, 898989);
            // console.log(row, 898989);
            add(row).then(() => {
                this.initFlag = false;
src/views/exam/examination.vue
@@ -96,7 +96,7 @@
    data () {
        var validatePass = (rule, value, callback) => {
            console.log(value)
            // console.log(value)
            if (value == undefined || value == '') {
                callback(new Error('请输入分数'));
                return;
src/views/exam/performance.vue
@@ -78,7 +78,7 @@
    data () {
        var validatePass = (rule, value, callback) => {
            console.log(value)
            // console.log(value)
            if (value == undefined || value == '') {
                callback(new Error('请输入实操成绩'));
                return;
src/views/exam/startexam.vue
@@ -118,7 +118,7 @@
      // this.startTime = this.getCurrentTimes();
    },
    countDownE_c: function() {
      messageWarn(this, "考试结束123");
      messageWarn(this, "考试结束");
      this.overExam();
      //   this.disableSubmit = true;
      // this.submitExam("over");
@@ -140,7 +140,7 @@
      var that = this;
      if (that.option.data[0].isExam == 3) {
        that.resData["examScoreId"] = that.scoreId;
        console.log(that.resData);
        // console.log(that.resData);
        that.$router.push({
          path: `/startexam/${that.resData.scoreId}`,
          query: that.resData
@@ -181,6 +181,7 @@
      //   // type: "warning",
      // });
      // return;
      // debugger;
      updateApplyStatus(data).then(res => {
        that.resData["examScoreId"] = res.data.id;
        this.$store.commit("SetScoreId", res.data.id);
@@ -201,6 +202,7 @@
      });
    },
    getUserInfoBYExam() {
      console.log(this.option,456123)
      var that = this;
      let setData = ({ color, subtext, isExam }) => {
        that.option.data = [
@@ -239,37 +241,44 @@
        that.$store.commit("SetexamUserData", that.option.data[0]);
      };
      var duibiTime = function(newTime, oldTime) {
        var newYear = newTime.split(" ")[0],
          newDat = newTime.split(" ")[1],
          oldYear = oldTime.split(" ")[0],
          oldDat = oldTime.split(" ")[1];
        if (newYear !== oldYear) {
          return false;
        } else {
          let newD = {
            s: +newDat.split(":")[0],
            f: +newDat.split(":")[1],
            m: +newDat.split(":")[2]
          };
          let oldD = {
            s: +oldDat.split(":")[0],
            f: +oldDat.split(":")[1],
            m: +oldDat.split(":")[2]
          };
          if (newD.s - oldD.s > 1) {
            return false;
          } else if (newD.s - oldD.s == 1) {
            if (newD.f < oldD.f) {
              return oldD.f - newD.f;
            } else {
              return false;
            }
          } else if (newD.s == oldD.s) {
            return 60 - (newD.f - oldD.f);
          }
          // return [newD, oldD];
          return false;
        }
        var newtimes = new Date(newTime.replace(/-/g,'/')).getTime();
        var oldtimes = new Date(oldTime.replace(/-/g,'/')).getTime();
        var dif = Math.ceil((newtimes - oldtimes)/(1000*60))
        return 90-dif
        // var newYear = newTime.split(" ")[0],
        //   newDat = newTime.split(" ")[1],
        //   oldYear = oldTime.split(" ")[0],
        //   oldDat = oldTime.split(" ")[1];
        //   debugger;
        // if (newYear !== oldYear) {
        //   return false;
        // } else {
        //   let newD = {
        //     s: +newDat.split(":")[0],
        //     f: +newDat.split(":")[1],
        //     m: +newDat.split(":")[2]
        //   };
        //   let oldD = {
        //     s: +oldDat.split(":")[0],
        //     f: +oldDat.split(":")[1],
        //     m: +oldDat.split(":")[2]
        //   };
        //   if (newD.s - oldD.s > 1) {
        //     return false;
        //   } else if (newD.s - oldD.s == 1) {
        //     if (newD.f < oldD.f) {
        //       // return oldD.f - newD.f;
        //       return 90 - (newD.f - oldD.f);
        //     } else {
        //       return false;
        //     }
        //   } else if (newD.s == oldD.s) {
        //     return 90 - (newD.f - oldD.f);
        //   }
        //   // return [newD, oldD];
        //   return false;
        // }
        // return false;
      };
@@ -281,7 +290,7 @@
          that.resData = res.data.data[0];
          var data = res.data.data[0];
          // console.log(data,333);
          //当前时间
          var nowD,
            startD = new Date(data.startTime),
@@ -311,6 +320,7 @@
            }
            // console.log(data, 123456);
            if (data.isExam == 3) {
              that.$store.commit("SetScoreId",  data.scoreId);
              this.scoreId = data.scoreId;
              setData({ color: "success", subtext: "继续考试", isExam: 3 });
              const currentTimeSTART = moment(data.examStartTime);
src/views/startexam/index.vue
@@ -11,19 +11,9 @@
                    <div class="time-remain_title">剩余时间 :</div>
                    <div class="time">
                      <count-down
                        v-on:start_callback="countDownS_cb(1)"
                        v-on:end_callback="countDownE_cb(1)"
                        :current-time="currentTime"
                        :start-time="startTime"
                        :end-time="endTime"
                        :tip-text="'距离考试开始'"
                        :tip-text-end="'距离考试结束'"
                        :end-text="'考试结束'"
                        :hourTxt="':'"
                        :minutesTxt="':'"
                        :secondsTxt="''"
                      >
                      <count-down v-on:start_callback="countDownS_cb(1)" v-on:end_callback="countDownE_cb(1)"
                        :current-time="currentTime" :start-time="startTime" :end-time="endTime" :tip-text="'距离考试开始'"
                        :tip-text-end="'距离考试结束'" :end-text="'考试结束'" :hourTxt="':'" :minutesTxt="':'" :secondsTxt="''">
                      </count-down>
                    </div>
                  </div>
@@ -31,13 +21,8 @@
                    当前进度: {{ subjectIndex }}/{{ subjectIds.length }}
                  </div>
                  <div class="answer-card">
                    <el-button
                      type="text"
                      icon="el-icon-date el-dates"
                      class="el-dates"
                      @click="answerCard"
                      >答题卡</el-button
                    >
                    <el-button type="text" icon="el-icon-date el-dates" class="el-dates"
                      @click="answerCard">答题卡</el-button>
                  </div>
                  <!-- <el-button
                    type="success"
@@ -59,34 +44,19 @@
                    <!-- 题目内容 -->
                    <choices ref="choices" v-show="this.query.type === 0" />
                    <multiple-choices
                      ref="multipleChoices"
                      v-show="this.query.type === 1"
                    />
                    <multiple-choices ref="multipleChoices" v-show="this.query.type === 1" />
                    <judgement ref="judgement" v-show="this.query.type === 2" />
                    <practical-operation
                      ref="practicalOperation"
                      v-show="this.query.type === 3"
                    />
                    <practical-operation ref="practicalOperation" v-show="this.query.type === 3" />
                    <short-answer
                      ref="shortAnswer"
                      v-show="this.query.type === 4"
                    />
                    <short-answer ref="shortAnswer" v-show="this.query.type === 4" />
                    <div class="subject-buttons" v-if="query.subjectId !== ''">
                      <!-- <el-button plain @click="last" :loading="loadingLast"
                      >上一题</el-button
                    > -->
                      <el-button
                        @click="next"
                        class="buttons"
                        :loading="loadingNext"
                        type="primary"
                        >下一题</el-button
                      >
                      <el-button @click="next" class="buttons" :loading="loadingNext" type="primary">下一题</el-button>
                      <!-- <el-button
                      :disabled="timesIT"
                      type="success"
@@ -100,26 +70,15 @@
                      "
                      >完成考试 {{ time }}</el-button
                    > -->
                      <el-button
                        type="success"
                        @click="submitExam"
                        :disabled="subjectIndex != 60"
                        >完成考试 {{ time }}
                      <el-button type="success" @click="submitExam" :disabled="subjectIndex != 100">完成考试 {{ time }}
                      </el-button>
                    </div>
                  </div>
                </div>
              </el-col>
            </el-row>
            <el-dialog
              title="答题卡"
              :visible.sync="dialogVisible"
              width="50%"
              top="10vh"
              :modal="false"
              center
              class="datika"
            >
            <el-dialog title="答题卡" :visible.sync="dialogVisible" width="50%" top="10vh" :modal="false" center
              class="datika">
              <div class="answer-card-title">
                {{ exam.examinationName }}(共{{
                  subjectIds.length
@@ -135,13 +94,9 @@
                  :key="index"
                  @click="toSubject(value.everyID, value.type, index)"
                  >&nbsp;{{ index + 1 }}&nbsp;</el-button> -->
                <el-button
                  circle
                  v-for="(value, index) in subjectIds"
                  :style="{ background: value.color, color: value.fontColor }"
                  :key="index"
                  >&nbsp;{{ index + 1 }}&nbsp;</el-button
                >
                <el-button circle v-for="(value, index) in subjectIds"
                  :style="{ background: value.color, color: value.fontColor }" :key="index">&nbsp;{{ index + 1
                  }}&nbsp;</el-button>
                <!-- @click="toSubject(value.everyID, value.type, index)" -->
              </el-row>
            </el-dialog>
@@ -293,20 +248,20 @@
    }
  },
  methods: {
    countDownS_cb: function() {
    countDownS_cb: function () {
      // console.log(12456);
      messageSuccess(this, "考试开始");
      this.startTime = this.getCurrentTimes();
    },
    countDownE_cb: function() {
    countDownE_cb: function () {
      messageWarn(this, "考试结束");
      //   this.disableSubmit = true;
      // this.submitExam("over");
      this.submitExam("over");
    },
    bottonControl(time) {
      //倒计时循环
      let times = time * 60;
      var setTime = function(time) {
      var setTime = function (time) {
        let a, b, d;
        a = parseInt(time / 60);
        b = time - a * 60;
@@ -343,7 +298,6 @@
    validateExamTime() {
      getCurrentTime()
        .then(response => {
          // console.log(response, 7777);
          const currentTime = moment(response.data.data);
          if (currentTime.isAfter(this.exam.endTime)) {
            messageWarn(this, "考试已结束");
@@ -360,8 +314,8 @@
              this.startTime = current;
              this.subjectStartTime = current;
              //   // this.endTime = moment(this.exam.endTime).valueOf()
              this.endTime = current + 60 * 60 * 1000;
              this.bottonControl(60);
              this.endTime = current + 90 * 60 * 1000;
              this.bottonControl(90);
            }
            // this.disableSubmit = false;
          }
@@ -372,7 +326,7 @@
    },
    startExam(currentTime) {
      var scoreId = window.localStorage.getItem("scoreId");
      // console.log(scoreId, this.first, "scoreIdscoreIdscoreIdscoreId");
      console.log(scoreId, this.first, "scoreIdscoreIdscoreIdscoreId");
      this.subjectIds = [];
      // if (this.first) {
      //   const current = currentTime.valueOf();
@@ -455,38 +409,44 @@
            }
            //适应时间
            const datyTime = objs.examScore.examTime;
            // console.log(objs, "datyTimedatyTimedatyTime");
            var duibiTime = function(newTime, oldTime) {
              var newYear = newTime.split(" ")[0],
                newDat = newTime.split(" ")[1],
                oldYear = oldTime.split(" ")[0],
                oldDat = oldTime.split(" ")[1];
              if (newYear !== oldYear) {
                return false;
              } else {
                let newD = {
                  s: +newDat.split(":")[0],
                  f: +newDat.split(":")[1],
                  m: +newDat.split(":")[2]
                };
                let oldD = {
                  s: +oldDat.split(":")[0],
                  f: +oldDat.split(":")[1],
                  m: +oldDat.split(":")[2]
                };
                if (newD.s - oldD.s > 1) {
                  return false;
                } else if (newD.s - oldD.s == 1) {
                  if (newD.f < oldD.f) {
                    return oldD.f - newD.f;
                  } else {
                    return false;
                  }
                } else if (newD.s == oldD.s) {
                  return 60 - (newD.f - oldD.f);
                }
                return [newD, oldD];
              }
            var duibiTime = function (newTime, oldTime) {
              var newtimes = new Date(newTime.replace(/-/g, '/')).getTime();
              var oldtimes = new Date(oldTime.replace(/-/g, '/')).getTime();
              var dif = Math.ceil((newtimes - oldtimes) / (1000 * 60))
              return 90 - dif
              // var newYear = newTime.split(" ")[0],
              //   newDat = newTime.split(" ")[1],
              //   oldYear = oldTime.split(" ")[0],
              //   oldDat = oldTime.split(" ")[1];
              // if (newYear !== oldYear) {
              //   return false;
              // } else {
              //   let newD = {
              //     s: +newDat.split(":")[0],
              //     f: +newDat.split(":")[1],
              //     m: +newDat.split(":")[2]
              //   };
              //   let oldD = {
              //     s: +oldDat.split(":")[0],
              //     f: +oldDat.split(":")[1],
              //     m: +oldDat.split(":")[2]
              //   };
              //   if (newD.s - oldD.s > 1) {
              //     return false;
              //   } else if (newD.s - oldD.s == 1) {
              //     if (newD.f < oldD.f) {
              //       return oldD.f - newD.f;
              //     } else {
              //       return false;
              //     }
              //   } else if (newD.s == oldD.s) {
              //     return 90 - (newD.f - oldD.f);
              //   }
              //   return [newD, oldD];
              // }
              // return false;
            };
            var listTime = duibiTime(currentTime._i, datyTime);
@@ -703,7 +663,7 @@
            }
            this.setSubjectInfo(subject);
            console.log(subject);
            // console.log(subject);
            this.$store.commit("setWindowSizeHeightAdd");
            // store.dispatch('SetSubjectInfo', subject).then(() => { })
@@ -842,7 +802,7 @@
          this.disableSubmit = true;
          this.doSubmitExam();
        })
        .catch(() => {});
        .catch(() => { });
    },
    doSubmitExam() {
      var obj = {
@@ -859,9 +819,9 @@
        examResultVOS: null
      };
      var arr = [];
      console.log(this.subjectIds);
      // console.log(this.subjectIds);
      // debugger;
      console.log(this.subjectIds.length, 111);
      // console.log(this.subjectIds.length, 111);
      for (var i = 0; i < this.subjectIds.length; i++) {
        let item = this.subjectIds[i];
        // console.log(item.answer, i);
@@ -1061,34 +1021,41 @@
$fontSize1: 18px;
$fontSize2: 20px;
$fontSize3: 40px;
.subject-box {
  margin-top: 25px;
  margin-left: 20px;
  height: 100%;
}
.subject-box-card {
  font-size: 28px;
  width: 80%;
  margin-bottom: 30px;
  min-height: 400px;
}
.subject-buttons {
  text-align: left;
  position: relative;
  top: 70px;
  left: 390px;
  // top: 70%;
  // right: 30%;
  .buttons {
    // border: 1px solid green;
  }
}
.tool-bar {
  margin-left: 20px;
}
.time-remain_title {
  font-size: $fontSize2;
}
.time-remain .time {
  display: block;
  font-size: $fontSize3;
@@ -1098,18 +1065,23 @@
  position: relative;
  //   top: -20px;
}
.current-progress {
  font-size: $fontSize2;
}
.answer-card {
  margin: 15px 0;
}
.el-dates {
  font-size: $fontSize1;
}
.subject-exam-title {
  margin-bottom: 25px;
}
/* 答题卡 */
.answer-card-title {
  font-size: 24px;
@@ -1117,23 +1089,27 @@
  line-height: 17px;
  padding: 10px 0;
}
.answer-card-split {
  width: 100%;
  border-bottom: 1px solid #e6e6e6;
}
.answer-card-content {
  padding-bottom: 10px;
  font-size: 0;
  margin-right: -15px;
  > button {
  >button {
    margin-top: 5px;
  }
}
.answered {
  background-color: greenyellow;
}
#avue-view > .morpheus-box {
#avue-view>.morpheus-box {
  position: absolute;
  width: calc(100% - 100px);
  height: 85%;
@@ -1143,10 +1119,13 @@
  padding: 10px !important;
  box-sizing: border-box;
}
.exam-card-body {
  // border-top: 5px solid #ffa820 !important;
}
$sizeBut: 50px;
.el-button.is-circle {
  text-align: center;
  width: $sizeBut !important;
vue.config.js
@@ -1,6 +1,6 @@
module.exports = {
    //路径前缀
    publicPath: "/",
    publicPath: "./",
    lintOnSave: true,
    productionSourceMap: false,
    chainWebpack: (config) => {
@@ -31,7 +31,7 @@
                // target: 'http://192.168.0.114:81',
                target: 'http://localhost:81',
                // target: 'http://172.20.10.2:81',
                // target: 'http://223.82.109.183:2080/api',
                // target: 'http://60.220.177.113:2081/api',
                //远程演示服务地址,可用于直接启动项目
                // target: 'http://2h3f861221.wicp.vip:58646',
                ws: true,