Browse Source

Merge branch 'feature-private' into 'PrivateRelease'

Feature private

See merge request crowd-2019/crowd-test-service-front!169
wangjin 4 years ago
parent
commit
bf06cb4771

+ 11 - 10
config/dev.env.js

@@ -1,19 +1,20 @@
 'use strict'
+
 const merge = require('webpack-merge')
 const prodEnv = require('./prod.env')
 
-// module.exports = merge(prodEnv, {
-//   NODE_ENV: '"development"',
-//   ENV_CONFIG: "'dev'",
-//   API_ROOT: '"//127.0.0.1"',
-//   LOGIN_URL: '"http://127.0.0.1:8081/page/login?redirect=http%3a%2f%2f127.0.0.1%2f%23%2fhome"',
-//   REGISTER_URL: '"http://127.0.0.1:8081/page/register"'
-// })
-
-module.exports = merge(prodEnv, {
+module.exports = {
   NODE_ENV: '"development"',
   ENV_CONFIG: "'dev'",
   API_ROOT: '"//crowd.dev.mooctest.net"',
   LOGIN_URL: '"http://user.mooctest.net:8081/page/login?redirect=http%3a%2f%2fcrowd.dev.mooctest.net%2f%23%2fhome"',
   REGISTER_URL: '"http://user.mooctest.net:8081/page/register"'
-})
+}
+
+// module.exports = {
+//   NODE_ENV: '"development"',
+//   ENV_CONFIG: "'dev'",
+//   API_ROOT: '"//127.0.0.1"',
+//   LOGIN_URL: '"http://127.0.0.1:8081/page/login?redirect=http%3a%2f%2fcrowd.dev.mooctest.net%2f%23%2fhome"',
+//   REGISTER_URL: '"http://127.0.0.1:8081/page/register"'
+// }

+ 2 - 0
package.json

@@ -29,6 +29,8 @@
     "webpack-dev-server": "^2.11.5"
   },
   "devDependencies": {
+    "@babel/preset-env": "^7.12.11",
+    "@babel/register": "^7.12.10",
     "autoprefixer": "^7.1.2",
     "babel-core": "^6.22.1",
     "babel-eslint": "^8.2.1",

+ 15 - 8
src/components/commons/Footer2.0.vue

@@ -4,22 +4,22 @@
       <el-row style="height: 120px">
         <el-col :span="5" class="nav-logo-block">
           <div class="nav-title-wrapper">
-            <img :src="require('../../assets/image/' + logo_white)" alt="logo" class="nav-logo">
+            <img :src="logo_white" alt="logo" class="nav-logo">
             <div class="nav-title">
-              标准驱动的集成化众测服务<br/>
-              平台及示范应用
+              {{ footer_title_one }}<br/>
+              {{ footer_title_two }}
             </div>
           </div>
         </el-col>
         <el-col :span="19" style="padding-left: 15%">
           <div class="copyright-block pull-left" style="margin: 12px 0">
             版权所有©信息产品及科技服务集成化众测服务平台与应用项目组<br/>
-            <a href="http://www.beian.miit.gov.cn/" style="color: white; font-size: 16px">粤ICP备09019504号</a><br/>
-            电话:020-32068333-223  传真:020-32068111<br/>
-            电子邮箱:topstest@gdsoftpark.com
+            <a href="http://www.beian.miit.gov.cn/" style="color: white; font-size: 16px">{{ footer_provider_number }}</a><br/>
+            电话:{{ footer_mobile }}  传真:{{ footer_fax }}1<br/>
+            电子邮箱:{{ footer_email }}
           </div>
           <div class="code-block pull-right">
-            <img src="../../assets/img/QRcode.png" alt="QRcode" class="mooctest-code" style="width: 110px;height: 110px;display: block">
+            <img :src="footer_QRcode" alt="QRcode" class="mooctest-code" style="width: 110px;height: 110px;display: block">
             <div style="width: 110px;text-align: center">官方微信公众号</div>
           </div>
         </el-col>
@@ -35,7 +35,14 @@ export default {
   name: "Footer2.0",
   data(){
     return{
-      logo_white:CONFIG.logo_white
+      logo_white:CONFIG.logo_white,
+      footer_title_one:CONFIG.footer_title_one,
+      footer_title_two:CONFIG.footer_title_two,
+      footer_provider_number:CONFIG.footer_provider_number,
+      footer_mobile:CONFIG.footer_mobile,
+      footer_fax:CONFIG.footer_fax,
+      footer_email:CONFIG.footer_email,
+      footer_QRcode:CONFIG.footer_QRcode,
     }
   }
 }

+ 1 - 1
src/components/commons/Header.vue

@@ -329,7 +329,7 @@
     storageSave
   } from '@/js/index'
   import {notify} from '@/constants/index'
-  import {logoTitle} from "../../config";
+  import {CONFIG} from "../../config";
 
   export default {
   name: 'header-container',

+ 5 - 16
src/components/commons/Header2.0.vue

@@ -44,8 +44,9 @@
             <li v-if="!isLogin">
               <a :href="registerUrl">免费注册</a>
             </li>
-              <span v-if="!isLogin">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;</span>
+
             <li v-if="isLogin">
+              <span v-if="!isLogin">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;</span>
               <router-link v-if="isLogin" to="/mine">
                 <a class="dropdown-toggle nav-link" data-toggle="dropdown">
 <!--                  <img class="icon" src="@/assets/img/mine_icon.svg">-->
@@ -67,18 +68,6 @@
               <a href="http://47.98.174.59:8101/home">后台管理</a>
             </li>
 
-            <!--            <span v-if="isLogin">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;</span>-->
-<!--            <li>-->
-<!--              <a @click="gotoHome" style="cursor: pointer">首页</a>-->
-<!--            </li>-->
-<!--            &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;-->
-<!--            <li>-->
-<!--              <a href="#">机构入驻</a>-->
-<!--            </li>-->
-<!--            &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;-->
-<!--            <li>-->
-<!--              <a href="#">客服中心</a>-->
-<!--            </li>-->
           </ul>
         </div>
     </div>
@@ -101,7 +90,7 @@
   import Http from '@/js/http.js'
   import Apis from '@/js/api.js'
   import {mapActions} from 'vuex'
-
+  import {login_url,register_url} from '../../config/index'
   export default {
     name: "Header2.0",
     data(){
@@ -109,8 +98,8 @@
         user: {},
         loading: false,
         fullScreenLoading: true,
-        loginUrl: process.env.LOGIN_URL,
-        registerUrl: process.env.REGISTER_URL,
+        loginUrl: login_url,
+        registerUrl: register_url,
         authInfo: {},
         isShowAuthCheckingDialog: false,
         isShowAuthRejectDialog: false,

+ 5 - 3
src/components/commons/HomeSlice.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="home-slice">
+  <div class="home-slice" :style="{backgroundImage: 'url('+ home_background_url +')'}">
     <el-row style="padding-top: 40px">
       <div class="slice-wrapper">
         <div class="slice-title">{{ title }}</div>
@@ -29,10 +29,12 @@ export default {
   data() {
     return {
       user: {},
+      home_background_url:CONFIG.home_background_url,
       isLogin: false,
       loading: false,
       title:CONFIG.title,
-      subtitle:CONFIG.subtitle
+      subtitle:CONFIG.subtitle,
+
     }
   },
   methods: {
@@ -97,7 +99,7 @@ export default {
 <style scoped lang="scss">
 @import "../../style/main";
 .home-slice {
-  background-image: url("../../assets/image/slice.png");
+  background-image: var(home_background_url);
   text-align: center;
 }
 .slice-title {

+ 900 - 850
src/components/task/Task.vue

@@ -3,112 +3,114 @@
     <div class="title h1" v-if="!isModifyMode">任务</div>
     <div class="create-body">
       <div class="title h2" v-if="!isModifyMode">基本信息</div>
-      <el-form :model="task" :rules="rules" ref="task" label-width="120px" class="demo-task"
-               style="margin:0 100px;">
-        <el-form-item label="任务名称" prop="title" style="width: 700px;">
-          <el-input size="small" v-if="isModifyMode" v-model="task.title"></el-input>
-          <span v-if="!isModifyMode">{{task.title}}</span>
-          <el-tag v-if="!isModifyMode" :type="task.statusVO&&task.statusVO.style">{{task.statusVO ?
-            task.statusVO.text:''}}
-          </el-tag>
-        </el-form-item>
-        <el-form-item label="任务描述" prop="desc" style="width: 700px;">
-          <el-input autosize v-if="isModifyMode" type="textarea" v-model="task.description"></el-input>
-          <span v-if="!isModifyMode">{{task.description ? task.description : '暂无'}}</span>
-        </el-form-item>
-        <el-form-item label="任务报价" prop="quotePrice" style="width: 700px;">
-          <el-input size="small" type="number" v-if="isModifyMode" v-model="task.quotePrice">
-            <template slot="append">¥</template>
-          </el-input>
-          <span v-if="!isModifyMode">¥{{task.quotePrice}}</span>
-        </el-form-item>
-        <!--<el-form-item type="number" label="任务定价" prop="fixedPrice">-->
-        <!--<el-input v-if="isModifyMode" v-model="task.fixedPrice">-->
-        <!--<template slot="append">¥</template>-->
-        <!--</el-input>-->
-        <!--<span v-if="!isModifyMode">{{task.fixedPrice}}</span>-->
-        <!--</el-form-item>-->
-        <el-form-item label="测试类型" prop="serviceType">
-          <el-radio-group v-if="isModifyMode" v-model="task.serviceType" @change="handleTestTypeChange">
+      <el-row :gutter="20">
+        <el-col :span="15">
+          <el-form :model="task" :rules="rules" ref="task" label-width="120px" class="demo-task"
+                   style="margin:0 80px;">
+            <el-form-item label="任务名称" prop="title" style="width: 700px;">
+              <el-input size="small" v-if="isModifyMode" v-model="task.title"></el-input>
+              <span v-if="!isModifyMode">{{task.title}}</span>
+              <el-tag v-if="!isModifyMode" :type="task.statusVO&&task.statusVO.style">{{task.statusVO ?
+                task.statusVO.text:''}}
+              </el-tag>
+            </el-form-item>
+            <el-form-item label="任务描述" prop="description" style="width: 700px;">
+              <el-input autosize v-if="isModifyMode" type="textarea" v-model="task.description"></el-input>
+              <span v-if="!isModifyMode">{{task.description ? task.description : '暂无'}}</span>
+            </el-form-item>
+            <el-form-item label="任务报价" prop="quotePrice" style="width: 700px;">
+              <el-input size="small" type="number" v-if="isModifyMode" v-model="task.quotePrice">
+                <template slot="append">¥</template>
+              </el-input>
+              <span v-if="!isModifyMode">¥{{task.quotePrice}}</span>
+            </el-form-item>
+            <!--<el-form-item type="number" label="任务定价" prop="fixedPrice">-->
+            <!--<el-input v-if="isModifyMode" v-model="task.fixedPrice">-->
+            <!--<template slot="append">¥</template>-->
+            <!--</el-input>-->
+            <!--<span v-if="!isModifyMode">{{task.fixedPrice}}</span>-->
+            <!--</el-form-item>-->
+            <el-form-item label="测试类型" prop="serviceType">
+              <el-radio-group v-if="isModifyMode" v-model="task.serviceType" @change="handleTestTypeChange">
             <span v-for="(item,index) in serviceType" :key="index">
               <el-radio :label="item.code" name="serviceType">{{item.name}}</el-radio>
             </span>
-          </el-radio-group>
-          <span class="badge" v-if="!isModifyMode">{{serviceName}}</span>
-        </el-form-item>
-
-        <el-form-item label="服务序列号" prop="endPoint" style="width: 700px;"
-                      v-if="showBD&&task.endPoint&&currType.type===1"
-                      >
-          <el-input v-if="isModifyMode" v-model="task.endPoint.serverCode" label="examId"></el-input>
-          <span v-if="!isModifyMode&&showBD">{{task.endPoint.serverCode}}</span>
-        </el-form-item>
-
-        <el-form-item label="任务可见性" prop="resource" style="width: 700px;">
-          <div v-if="!isModifyMode">
-            <!--<div v-if="task.resource=='1'">{{updateLocation(task.location)}}</div>-->
-            <div v-if="task.resource==0">定向</div>
-            <div v-if="task.resource==2">{{resourceType[task.resource]}}</div>
-          </div>
-          <el-tabs
-            :tab-position="tabPosition"
-            v-model="task.resource"
-            style="max-height: 200px;"
-            v-if="isModifyMode"
-          >
-            <el-tab-pane :label="resourceType[0]" name="0">
-              <el-radio-group v-model="task.institution" @change="handleTestTypeChange">
-                <el-radio
-                  :label="item"
-                  name="type"
-                  v-for="item,index in institutionArray"
-                  :key="index"
-                >{{item.evaluationAgencyName}}
-                </el-radio>
               </el-radio-group>
-            </el-tab-pane>
-            <!--<el-tab-pane :label="resourceType[1]" name="1">-->
-            <!--<provincecity-->
-            <!--ref="addFormProvince"-->
-            <!--@selectChange="locationChange"-->
-            <!--:provinceCode="task.location == null ||task.location.provinceCode==null?'3200':task.location.provinceCode"-->
-            <!--:cityCode="task.location == null ||task.location.cityCode==null?'3201':task.location.cityCode"-->
-            <!--&gt;</provincecity>-->
-            <!--</el-tab-pane>-->
-            <el-tab-pane :label="resourceType[2]" name="2"></el-tab-pane>
-          </el-tabs>
-        </el-form-item>
-        <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===0">
-          <el-input-number v-model="task.participantCount" :min="1" :max="1000" label="领取人数"></el-input-number>
-        </el-form-item>
-        <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===1">
-          <el-input-number v-model="task.participantCount" :min="2" :max="1000" label="领取人数"></el-input-number>
-        </el-form-item>
-        <el-form-item label="领取人数" prop="quotePrice" v-if="!isModifyMode">
-          {{task.acceptedCount }}/{{ task.participantCount}}
-        </el-form-item>
-        <el-form-item label="需求文档" prop="doc">
-          <el-upload
-            style="width: 400px"
-            v-if="isModifyMode"
-            drag
-            class="upload-demo"
-            action=""
-            :on-remove="handleRemove"
-            :before-remove="beforeRemove"
-            :limit="1"
-            :on-exceed="handleExceed"
-
-            :http-request="uploadRequireDoc"
-            :file-list="task.doc"
-          >
-            <i class="el-icon-upload"></i>
-            <div class="el-upload__text">
-              将文件拖到此处,或
-              <em>点击上传</em>
-            </div>
-          </el-upload>
-          <span>
+              <span class="badge" v-if="!isModifyMode">{{serviceName}}</span>
+            </el-form-item>
+
+            <el-form-item label="服务序列号" prop="endPoint" style="width: 700px;"
+                          v-if="showBD&&task.endPoint&&currType.type===1"
+            >
+              <el-input v-if="isModifyMode" v-model="task.endPoint.serverCode" label="examId"></el-input>
+              <span v-if="!isModifyMode&&showBD">{{task.endPoint.serverCode}}</span>
+            </el-form-item>
+
+            <el-form-item label="任务可见性" prop="resource" style="width: 700px;">
+              <div v-if="!isModifyMode">
+                <!--<div v-if="task.resource=='1'">{{updateLocation(task.location)}}</div>-->
+                <div v-if="task.resource==0">定向</div>
+                <div v-if="task.resource==2">{{resourceType[task.resource]}}</div>
+              </div>
+              <el-tabs
+                :tab-position="tabPosition"
+                v-model="task.resource"
+                style="max-height: 200px;"
+                v-if="isModifyMode"
+              >
+                <el-tab-pane :label="resourceType[0]" name="0">
+                  <el-radio-group v-model="task.institution" @change="handleTestTypeChange">
+                    <el-radio
+                      :label="item"
+                      name="type"
+                      v-for="item,index in institutionArray"
+                      :key="index"
+                    >{{item.evaluationAgencyName}}
+                    </el-radio>
+                  </el-radio-group>
+                </el-tab-pane>
+                <!--<el-tab-pane :label="resourceType[1]" name="1">-->
+                <!--<provincecity-->
+                <!--ref="addFormProvince"-->
+                <!--@selectChange="locationChange"-->
+                <!--:provinceCode="task.location == null ||task.location.provinceCode==null?'3200':task.location.provinceCode"-->
+                <!--:cityCode="task.location == null ||task.location.cityCode==null?'3201':task.location.cityCode"-->
+                <!--&gt;</provincecity>-->
+                <!--</el-tab-pane>-->
+                <el-tab-pane :label="resourceType[2]" name="2"></el-tab-pane>
+              </el-tabs>
+            </el-form-item>
+            <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===0">
+              <el-input-number v-model="task.participantCount" :min="1" :max="1000" label="领取人数"></el-input-number>
+            </el-form-item>
+            <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===1">
+              <el-input-number v-model="task.participantCount" :min="2" :max="1000" label="领取人数"></el-input-number>
+            </el-form-item>
+            <el-form-item label="领取人数" prop="quotePrice" v-if="!isModifyMode">
+              {{task.acceptedCount }}/{{ task.participantCount}}
+            </el-form-item>
+            <el-form-item label="需求文档" prop="doc">
+              <el-upload
+                style="width: 400px"
+                v-if="isModifyMode"
+                drag
+                class="upload-demo"
+                action=""
+                :on-remove="handleRemove"
+                :before-remove="beforeRemove"
+                :limit="1"
+                :on-exceed="handleExceed"
+
+                :http-request="uploadRequireDoc"
+                :file-list="task.doc"
+              >
+                <i class="el-icon-upload"></i>
+                <div class="el-upload__text">
+                  将文件拖到此处,或
+                  <em>点击上传</em>
+                </div>
+              </el-upload>
+              <span>
               <span v-if="task.requireDocUrl == null || task.requireDocUrl == ''">
                 <i class="el-icon-document"></i>暂无文件
               </span>
@@ -117,111 +119,120 @@
                   class="el-icon-document"></i>下载文档</el-link></a>
               </span>
             </span>
-        </el-form-item>
-
-        <el-form-item label="任务截止时间" prop="datetime">
-          <div class="block" v-if="isModifyMode">
-            <el-date-picker
-              size="small"
-              v-model="task.datetime"
-              type="datetime"
-              placeholder="选择截止时间"
-              align="right"
-              :picker-options="pickerOptions"
-            ></el-date-picker>
-          </div>
-          <span v-if="!isModifyMode">{{dateFormat(new Date(task.datetime),'yyyy-MM-dd HH:mm:ss')}}</span>
-        </el-form-item>
-        <el-form-item v-if="isModifyMode">
-          <div class="btn btn-small btn-info" @click="updateTask()">确认修改</div>
-          <!--<div class="btn btn-small" @click="resetForm()">重置</div>-->
-          <div class="btn btn-small" @click="cancelMode()">取消</div>
-        </el-form-item>
-
-        <el-form-item v-if="editShortLink && task.endPoint.serverCode && taskOperationControl.confirmFinish" label="任务面板链接" props="shortLink">
-          <el-input v-model="shortLink" placeholder="请输入短链接生成任务报告" style="width: 800px">
-            <template slot="append">
-              <el-button @click="getTaskDataBoard()">确定</el-button>
-            </template>
-          </el-input>
-        </el-form-item>
-
-        <el-form-item v-if="shortLink && !editShortLink" label="任务面板链接" props="shortLink">
-          {{shortLink}}
-          <i class="el-icon-edit" @click="editShortLink = true" v-if="taskOperationControl.confirmFinish"/>
-        </el-form-item>
-
-        <el-form-item v-if="!isModifyMode">
-          <el-button size="mini" @click="toProject()">项目详情</el-button>
-          <el-popover
-            placement="top-start"
-            title="确认结束?"
-            width="200"
-            trigger="hover"
-            content="测评机构已提交结束申请,请确认是否结束该任务">
-            <el-button v-if="taskOperationControl.confirmFinish" type="success" size="mini" slot="reference"
-                       @click="endTask()">确认结束
-            </el-button>
-          </el-popover>
-
-          <el-popover
-            placement="top-start"
-            title="确认提交?"
-            width="200"
-            trigger="hover"
-            content="提交任务后不可更改,等待区域管理员验收">
-            <el-button v-if="taskOperationControl.finish" type="primary" size="mini" slot="reference"
-                       @click="submitTaskRequest()">提交任务
-            </el-button>
-          </el-popover>
-
-          <el-popover
-            placement="top-start"
-            title="确认拒绝?"
-            width="200"
-            trigger="hover"
-            content="拒绝后不可再接收此任务,且该任务对您不可见">
-            <el-button v-if="taskOperationControl.reject" type="danger" size="mini" slot="reference"
-                       @click="rejectTask()">拒绝任务
-            </el-button>
-          </el-popover>
-
-          <el-popover
-            placement="top-start"
-            title="确认接收?"
-            width="200"
-            trigger="hover"
-            content="接收任务后请认真完成!">
-            <el-button v-if="taskOperationControl.receive" type="primary" size="mini" slot="reference"
-                       @click="receiveTask()">接收任务
-            </el-button>
-          </el-popover>
-
-          <el-button v-if="taskOperationControl.writeReport" type="primary" size="mini" @click="gotoWriteReport()">填写报告
-          </el-button>
-
-          <el-button v-if="taskOperationControl.update" type="primary" size="mini" @click="modifyForm()">修改任务
-          </el-button>
-          <el-button v-if="taskOperationControl.uploadReport" type="primary" size="mini" @click="toCreateReport()">
-            上传报告
-          </el-button>
-          <el-button v-if="taskOperationControl.taskDemonstrate" type="success" size="mini" @click="gotoDataboard()">
-            任务面板
-          </el-button>
-          <!--<div class="btn btn-small btn-info"-->
-          <!--v-if="taskOperationControl.confirmFinish"-->
-          <!--@click="endTask()">确认结束-->
-          <!--</div>-->
-          <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.finish" @click="submitTaskRequest()">提交任务-->
-          <!--</div>-->
-          <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.receive" @click="receiveTask()">接收任务</div>-->
-          <!--<div class="btn btn-small btn-danger" v-if="!taskOperationControl.reject" @click="rejectTask()">拒绝任务</div>-->
-          <!--<div class="btn btn-small btn-info" v-if="taskOperationControl.update" @click="modifyForm()">修改任务</div>-->
-          <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.uploadReport" @click="toCreateReport()">上传报告-->
-          <!--</div>-->
-
-        </el-form-item>
-      </el-form>
+            </el-form-item>
+
+            <el-form-item label="任务截止时间" prop="datetime">
+              <div class="block" v-if="isModifyMode">
+                <el-date-picker
+                  size="small"
+                  v-model="task.datetime"
+                  type="datetime"
+                  placeholder="选择截止时间"
+                  align="right"
+                  :picker-options="pickerOptions"
+                ></el-date-picker>
+              </div>
+              <span v-if="!isModifyMode">{{dateFormat(new Date(task.datetime),'yyyy-MM-dd HH:mm:ss')}}</span>
+            </el-form-item>
+            <el-form-item v-if="isModifyMode">
+              <div class="btn btn-small btn-info" @click="updateTask()">确认修改</div>
+              <!--<div class="btn btn-small" @click="resetForm()">重置</div>-->
+              <div class="btn btn-small" @click="cancelMode()">取消</div>
+            </el-form-item>
+
+            <el-form-item v-if="editShortLink && task.endPoint.serverCode && taskOperationControl.confirmFinish" label="任务面板链接" props="shortLink">
+              <el-input v-model="shortLink" placeholder="请输入短链接生成任务报告" style="width: 800px">
+                <template slot="append">
+                  <el-button @click="getTaskDataBoard()">确定</el-button>
+                </template>
+              </el-input>
+            </el-form-item>
+
+            <el-form-item v-if="shortLink && !editShortLink" label="任务面板链接" props="shortLink">
+              {{shortLink}}
+              <i class="el-icon-edit" @click="editShortLink = true" v-if="taskOperationControl.confirmFinish"/>
+            </el-form-item>
+
+            <el-form-item v-if="!isModifyMode">
+              <el-button size="mini" @click="toProject()">项目详情</el-button>
+              <el-popover
+                placement="top-start"
+                title="确认结束?"
+                width="200"
+                trigger="hover"
+                content="测评机构已提交结束申请,请确认是否结束该任务">
+                <el-button v-if="taskOperationControl.confirmFinish" type="success" size="mini" slot="reference"
+                           @click="endTask()">确认结束
+                </el-button>
+              </el-popover>
+
+              <el-popover
+                placement="top-start"
+                title="确认提交?"
+                width="200"
+                trigger="hover"
+                content="提交任务后不可更改,等待区域管理员验收">
+                <el-button v-if="taskOperationControl.finish" type="primary" size="mini" slot="reference"
+                           @click="submitTaskRequest()">提交任务
+                </el-button>
+              </el-popover>
+
+              <el-popover
+                placement="top-start"
+                title="确认拒绝?"
+                width="200"
+                trigger="hover"
+                content="拒绝后不可再接收此任务,且该任务对您不可见">
+                <el-button v-if="taskOperationControl.reject" type="danger" size="mini" slot="reference"
+                           @click="rejectTask()">拒绝任务
+                </el-button>
+              </el-popover>
+
+              <el-popover
+                placement="top-start"
+                title="确认接收?"
+                width="200"
+                trigger="hover"
+                content="接收任务后请认真完成!">
+                <el-button v-if="taskOperationControl.receive" type="primary" size="mini" slot="reference"
+                           @click="receiveTask()">接收任务
+                </el-button>
+              </el-popover>
+
+              <el-button v-if="taskOperationControl.writeReport" type="primary" size="mini" @click="gotoWriteReport()">填写报告
+              </el-button>
+
+              <el-button v-if="taskOperationControl.update" type="primary" size="mini" @click="modifyForm()">修改任务
+              </el-button>
+
+              <el-button v-if="taskOperationControl.taskRecommend" type="primary" size="mini" @click="recommendTask()">任务推荐
+              </el-button>
+
+              <el-button v-if="taskOperationControl.uploadReport" type="primary" size="mini" @click="toCreateReport()">
+                上传报告
+              </el-button>
+              <el-button v-if="taskOperationControl.taskDemonstrate" type="success" size="mini" @click="gotoDataboard()">
+                任务面板
+              </el-button>
+              <!--<div class="btn btn-small btn-info"-->
+              <!--v-if="taskOperationControl.confirmFinish"-->
+              <!--@click="endTask()">确认结束-->
+              <!--</div>-->
+              <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.finish" @click="submitTaskRequest()">提交任务-->
+              <!--</div>-->
+              <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.receive" @click="receiveTask()">接收任务</div>-->
+              <!--<div class="btn btn-small btn-danger" v-if="!taskOperationControl.reject" @click="rejectTask()">拒绝任务</div>-->
+              <!--<div class="btn btn-small btn-info" v-if="taskOperationControl.update" @click="modifyForm()">修改任务</div>-->
+              <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.uploadReport" @click="toCreateReport()">上传报告-->
+              <!--</div>-->
+            </el-form-item>
+          </el-form>
+        </el-col>
+        <el-col :span="9">
+          <TaskCloud :info="wordCloud" v-if="wordCloud.length"></TaskCloud>
+        </el-col>
+      </el-row>
+
     </div>
     <div class="create-body" v-if="!isModifyMode">
       <div class="title h2">用户报告列表</div>
@@ -251,677 +262,716 @@
 </template>
 
 <script>
-  import ResourceType from '@/constants/enum/resource-type.js'
-  import provincecity from '@/components/commons/ProvinceCity'
-  import ReportList from '@/components/report/ReportList'
-  import Http from '@/js/http.js'
-  import Apis from '@/js/api.js'
-  import {notify} from '@/constants/index'
-  import {
-    ensureEndTask,
-    getAllAgencies,
-    getAllServiceTypes,
-    getFormalTimeFromDate,
-    getProvinceCodeByProvinceName,
-    getProvinceNameByProvinceCode,
-    getTask,
-    receiveTaskRequest,
-    rejectTask,
-    storageGet,
-    submitTaskRequest,
-    updateTask
-  } from '@/js/index'
-
-  export default {
-    name: 'Task',
-    components: {
-      provincecity,
-      ReportList
-    },
-    data() {
-      return {
-        currType: {},
-        user: {},
-        serviceName:'',
-        showBD: true,
-        rolesPermissions: {},
-        loading: false,
-        isModifyMode: false,
-        institutionArray: [],
-        tabPosition: 'top',
-        resourceType: ResourceType,
-        serviceType: [],
-        taskId: '',
-        projectId: '',
-        taskOperationControl: {
-          confirmFinish: false,
-          finish: false,
-          receive: false,
-          update: false,
-          uploadReport: false
-        },
-        crowdReportUrl: '',
-        task: {
-          agencyId: '',
-          status: '',
-          name: '',
-          desc: '',
-          serviceType: '',
-          resource: '',
-          location: {},
-          institution: {},
-          datetime: '',
-          quotePrice: '',
-          fixedPrice: '',
-          doc: [],
-          requireDocUrl: '',
-          participantCount: 1,
-          title: '',
-          description: '',
-          endPoint: {
-            serverCode: '',
-            token: ''
+import ResourceType from '@/constants/enum/resource-type.js'
+import provincecity from '@/components/commons/ProvinceCity'
+import ReportList from '@/components/report/ReportList'
+import TaskCloud from '@/components/task/TaskCloud'
+import Http from '@/js/http.js'
+import Apis from '@/js/api.js'
+import {notify} from '@/constants/index'
+import {
+  ensureEndTask,
+  getAllAgencies,
+  getAllServiceTypes,
+  getFormalTimeFromDate,
+  getProvinceCodeByProvinceName,
+  getProvinceNameByProvinceCode,
+  getTask,
+  receiveTaskRequest,
+  rejectTask,
+  storageGet,
+  submitTaskRequest,
+  updateTask,
+  getTaskWordCloud
+} from '@/js/index'
+
+export default {
+  name: 'Task',
+  components: {
+    provincecity,
+    ReportList,
+    TaskCloud
+  },
+  data() {
+    return {
+      currType: {},
+      user: {},
+      serviceName:'',
+      showBD: true,
+      rolesPermissions: {},
+      loading: false,
+      isModifyMode: false,
+      institutionArray: [],
+      tabPosition: 'top',
+      resourceType: ResourceType,
+      serviceType: [],
+      taskId: '',
+      projectId: '',
+      taskOperationControl: {
+        confirmFinish: false,
+        finish: false,
+        receive: false,
+        update: false,
+        uploadReport: false,
+        writeReport: false,
+        taskDemonstrate: false,
+        taskRecommend: false
+      },
+      crowdReportUrl: '',
+      wordCloud:[],
+      task: {
+        agencyId: '',
+        status: '',
+        name: '',
+        desc: '',
+        serviceType: '',
+        resource: '',
+        location: {},
+        institution: {},
+        datetime: '',
+        quotePrice: '',
+        fixedPrice: '',
+        doc: [],
+        requireDocUrl: '',
+        participantCount: 1,
+        title: '',
+        description: '',
+        endPoint: {
+          serverCode: '',
+          token: ''
+        }
+      },
+      reportList: [],
+      pickerOptions: {
+        shortcuts: [
+          {
+            text: '今天',
+            onClick(picker) {
+              picker.$emit('pick', new Date())
+            }
+          },
+          {
+            text: '昨天',
+            onClick(picker) {
+              const date = new Date()
+              date.setTime(date.getTime() - 3600 * 1000 * 24)
+              picker.$emit('pick', date)
+            }
+          },
+          {
+            text: '一周前',
+            onClick(picker) {
+              const date = new Date()
+              date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
+              picker.$emit('pick', date)
+            }
           }
-        },
-        reportList: [],
-        pickerOptions: {
-          shortcuts: [
-            {
-              text: '今天',
-              onClick(picker) {
-                picker.$emit('pick', new Date())
+        ]
+      },
+      rules: {
+        title: [
+          {required: true, message: '请输入任务名称', trigger: 'blur'},
+          {min: 5, max: 50, message: '任务名称长度在 5 到 50 个字符', trigger: 'blur'}
+        ],
+        serviceType: [
+          {required: true, message: '测试类型不可为空', trigger: 'change'},
+        ],
+        description: [{required: true, message: '请填写描述', trigger: 'blur'}],
+        //price: [{required: true, message: '请填写价格', trigger: 'blur'}],
+        quotePrice: [
+          {required: true, message: '预算不可为空', trigger: 'blur'},
+          {
+            validator: (rule, value, callback) => {
+              if (value < 0) {
+                callback(new Error('请输入不小于0的数'))
+              } else {
+                callback()
               }
-            },
-            {
-              text: '昨天',
-              onClick(picker) {
-                const date = new Date()
-                date.setTime(date.getTime() - 3600 * 1000 * 24)
-                picker.$emit('pick', date)
+            }, trigger: 'blur'
+          },
+        ],
+        resource: [
+          {required: true},
+          {
+            validator: (rule, value, callback) => {
+              if (value == 0 && this.task.institution.id == null) {
+                callback(new Error('定向发布至少要选择一个测评机构'))
+              } else {
+                callback()
               }
-            },
-            {
-              text: '一周前',
-              onClick(picker) {
-                const date = new Date()
-                date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
-                picker.$emit('pick', date)
+            }, trigger: 'change'
+          },
+        ],
+        endPoint: [
+          {
+            validator: (rule, value, callback) => {
+              if (this.currType.type === 1 && this.task.endPoint.serverCode === '') {
+                callback(new Error('请填写对应得服务序列号'))
+              } else {
+                callback()
               }
-            }
-          ]
-        },
-        rules: {
-          title: [
-            {required: true, message: '请输入任务名称', trigger: 'blur'},
-            {min: 5, max: 50, message: '任务名称长度在 5 到 50 个字符', trigger: 'blur'}
-          ],
-          serviceType: [
-            {required: true, message: '测试类型不可为空', trigger: 'change'},
-          ],
-          desc: [{required: false, message: '请填写描述', trigger: 'blur'}],
-          //price: [{required: true, message: '请填写价格', trigger: 'blur'}],
-          quotePrice: [
-            {required: true, message: '预算不可为空', trigger: 'blur'},
-            {
-              validator: (rule, value, callback) => {
-                if (value < 0) {
-                  callback(new Error('请输入不小于0的数'))
-                } else {
-                  callback()
-                }
-              }, trigger: 'blur'
-            },
-          ],
-          resource: [
-            {required: true},
-            {
-              validator: (rule, value, callback) => {
-                if (value == 0 && this.task.institution.id == null) {
-                  callback(new Error('定向发布至少要选择一个测评机构'))
-                } else {
-                  callback()
-                }
-              }, trigger: 'change'
-            },
-          ],
-          endPoint: [
-            {
-              validator: (rule, value, callback) => {
-                if (this.currType.type === 1 && this.task.endPoint.serverCode === '') {
-                  callback(new Error('请填写对应得服务序列号'))
-                } else {
-                  callback()
-                }
-              }, trigger: ['change','blur']
-            },
-          ],
-          datetime: [{required: true, message: '截止时间不可为空', trigger: 'blur'}],
-        },
-        acceptedUserList: [],
-        shortLink:'',
-        editShortLink:false,
-      }
+            }, trigger: ['change','blur']
+          },
+        ],
+        datetime: [{required: true, message: '截止时间不可为空', trigger: 'blur'}],
+      },
+      acceptedUserList: [],
+      shortLink:'',
+      editShortLink:false,
+    }
+  },
+  watch: {
+    institutionArray(val) {
+      this.institutionArray = val
     },
-    watch: {
-      institutionArray(val) {
-        this.institutionArray = val
-      },
-      serviceType(val) {
-        this.serviceType = val
-      },
-      // 'task.institution' () {
-      //   if (this.task.institution) {
-      //     //this.$refs.addFormProvince.resetProviceCity()
-      //     this.task.location = {provinceCode: '', cityCode: ''}
-      //   }
-      // },
-      // 'task.location' () {
-      //   if (this.task.location.provinceCode || this.task.location.cityCode) {
-      //     this.task.institution = ''
-      //   }
-      // },
-      // 'task.resource' () {
-      //   if (this.task.resource == '广场') {
-      //     this.$refs.addFormProvince.resetProviceCity()
-      //     this.task.institution = ''
-      //     this.task.location = {provinceCode: '', cityCode: ''}
-      //   }
-      // },
-      deep: true
-    },
-    mounted() {
-      this.$nextTick(() => {
-        this.init()
+    serviceType(val) {
+      this.serviceType = val
+    },
+    // 'task.institution' () {
+    //   if (this.task.institution) {
+    //     //this.$refs.addFormProvince.resetProviceCity()
+    //     this.task.location = {provinceCode: '', cityCode: ''}
+    //   }
+    // },
+    // 'task.location' () {
+    //   if (this.task.location.provinceCode || this.task.location.cityCode) {
+    //     this.task.institution = ''
+    //   }
+    // },
+    // 'task.resource' () {
+    //   if (this.task.resource == '广场') {
+    //     this.$refs.addFormProvince.resetProviceCity()
+    //     this.task.institution = ''
+    //     this.task.location = {provinceCode: '', cityCode: ''}
+    //   }
+    // },
+    deep: true
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.init()
+    })
+  },
+  methods: {
+    //跳转到任务对应的数据面板
+    gotoDataboard(){
+      window.open(this.task.endPoint.token)
+    },
+    //根据短链接获取生成databoard
+    getTaskDataBoard(){
+      this.showLoading()
+      Http.put(`/api/project/${this.projectId}/task/${this.taskId}/addToken`,{"token":this.shortLink}).then((res)=>{
+        this.taskOperationControl = res.taskOperationControl;
+        this.task.endPoint = res.crowdTaskVO.endPointVO;
+        this.shortLink = res.crowdTaskVO.endPointVO.token;
+        if(this.shortLink != ''){
+          this.editShortLink = false;
+        }
+        this.hideLoading()
       })
     },
-    methods: {
-      //跳转到任务对应的数据面板
-      gotoDataboard(){
-        window.open(this.task.endPoint.token)
-      },
-      //根据短链接获取生成databoard
-      getTaskDataBoard(){
-        this.showLoading()
-        Http.put(`/api/project/${this.projectId}/task/${this.taskId}/addToken`,{"token":this.shortLink}).then((res)=>{
-          this.taskOperationControl = res.taskOperationControl;
-          this.task.endPoint = res.crowdTaskVO.endPointVO;
-          this.shortLink = res.crowdTaskVO.endPointVO.token;
-          if(this.shortLink != ''){
-            this.editShortLink = false;
-          }
-          this.hideLoading()
-        })
-      },
-      getServiceByCode(code){
-        let serviceName = this.serviceType.filter((item) => {
-          return item.code === code;
-        });
-        return serviceName&&serviceName[0]&&serviceName[0]['name']
-      },
+    getServiceByCode(code){
+      let serviceName = this.serviceType.filter((item) => {
+        return item.code === code;
+      });
+      return serviceName&&serviceName[0]&&serviceName[0]['name']
+    },
 
-      handleTestTypeChange(val) {
-        let type = this.serviceType.filter((item) => {
-          return item.code === val;
-        });
-        this.currType = type[0] ? type[0] : {};
-        if (this.currType.type === 0) {
-          this.$refs.task.clearValidate('endPoint');
-        }
-      },
-      init() {
-        this.taskId = this.$route.params.taskId
-        this.projectId = this.$route.params.projectId
-        this.setUserInfo()
-        this.setServiceType()
-        //this.loadData(this.projectId, this.taskId)
-        this.getTaskDetail()
-        this.setInstitutions()
-      },
+    handleTestTypeChange(val) {
+      let type = this.serviceType.filter((item) => {
+        return item.code === val;
+      });
+      this.currType = type[0] ? type[0] : {};
+      if (this.currType.type === 0) {
+        this.$refs.task.clearValidate('endPoint');
+      }
+    },
+    init() {
+      this.taskId = this.$route.params.taskId
+      this.projectId = this.$route.params.projectId
+      this.setUserInfo()
+      this.setServiceType()
+      //this.loadData(this.projectId, this.taskId)
+      this.getTaskDetail()
+      this.getWordCloud()
+      this.setInstitutions()
+    },
 
-      //北斗测试报告填写跳转
-      gotoWriteReport() {
-        window.open(this.crowdReportUrl, '_blank');
-      },
+    //北斗测试报告填写跳转
+    gotoWriteReport() {
+      window.open(this.crowdReportUrl, '_blank');
+    },
 
-      //跳转至项目详情页面
-      toProject() {
-        this.$router.push({
-          name: 'Project',
-          params: {projectId: this.projectId}
-        })
-      },
+    //跳转至项目详情页面
+    toProject() {
+      this.$router.push({
+        name: 'Project',
+        params: {projectId: this.projectId}
+      })
+    },
 
-      //切换至可编辑页面
-      modifyForm() {
-        // this.task.serviceType = ''
-        this.isModifyMode = true
-      },
-      //切换至不可编辑页面
-      cancelMode() {
-        this.isModifyMode = false
-      },
-      //重置表单
-      resetForm() {
-        this.task.name = ''
-        this.task.desc = ''
-        this.task.quotePrice = ''
-        this.task.fixedPrice = ''
-        this.task.type = ''
-        this.task.resource = '2' //如果是广场不用管Location和institution ,定向看institution,区域看location
-        this.task.location = {provinceCode: '', cityCode: ''}
-        this.task.institution = ''
-        this.task.datetime = ''
-        this.task.participantCount = 1
-        // this.task.endPointVO.caseId = ''
-        // this.task.endPointVO.examId = ''
-      },
-      //显示页面加载画面
-      showLoading() {
-        this.loading = true
-      },
-      //隐藏页面加载画面
-      hideLoading() {
-        this.loading = false
-      },
-      //加载用户信息
-      setUserInfo() {
-        this.user = storageGet('user')
-        this.rolesPermissions = storageGet('rolesPermissions')
-        if (storageGet('rolesPermissions').isRegionManager || storageGet('rolesPermissions').isSystemAdministrator) {
-          this.showBD = true;
-        } else {
-          this.showBD = false;
-        }
-      },
-      //加载任务的测试类型
-      setServiceType() {
-        getAllServiceTypes().then((res) => {
-          this.serviceType = res
-        }).catch((error) => {
-          notify('error', '加载测试类型失败')
-        })
-      },
-      //加载所有的测评机构
-      setInstitutions() {
-        getAllAgencies().then((res) => {
-          this.institutionArray = res
-        }).catch((error) => {
-          notify('error', '获取机构列表失败')
-        })
-      },
-      //获取任务详情
-      getTaskDetail() {
-        this.showLoading()
-        getTask(this.projectId, this.taskId, this.getTaskDetailSuccess, this.getTaskDetailFail)
-      },
-      //获取任务详情成功时回调函数
-      getTaskDetailSuccess(res) {
-        this.hideLoading()
-        // console.log(res)
-        this.taskId = res.crowdTaskVO.id
-        this.projectId = res.crowdTaskVO.projectId
-        this.task.title = res.crowdTaskVO.title
-        this.task.description = res.crowdTaskVO.description
-        this.task.serviceType = res.crowdTaskVO.serviceType
-        this.task.resource = res.crowdTaskVO.resource.toString()
-        this.task.location = getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
-        this.task.institution = res.crowdTaskVO.institution
-        this.task.datetime = new Date(res.crowdTaskVO.datetime)
-        this.task.quotePrice = res.crowdTaskVO.quotePrice
-        this.task.acceptedCount = res.crowdTaskVO.acceptedCount
-        this.task.participantCount = res.crowdTaskVO.participantCount
-        this.task.fixedPrice = res.crowdTaskVO.fixedPrice
-        this.task.doc = []
-        this.task.requireDocUrl = res.crowdTaskVO.requirementFile
-        this.task.agencyId = res.crowdTaskVO.agencyId
-        this.task.status = res.crowdTaskVO.status
-        this.task.statusVO = res.crowdTaskVO.statusVO
-        this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
-          serverCode: '',
-        }
-        this.taskOperationControl = res.taskOperationControl;
-        this.acceptedUserList = res.acceptedUserList;
-        this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
-        this.handleFormatReport(this.acceptedUserList);
-        this.handleTestTypeChange(res.crowdTaskVO.serviceType);
-        this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType);
-        if(res.crowdTaskVO.endPointVO){
-          if(res.crowdTaskVO.endPointVO.token){
-            this.shortLink = res.crowdTaskVO.endPointVO.token;
-            this.editShortLink = false
-          }else{
-            this.editShortLink = true
-          }
+    //切换至可编辑页面
+    modifyForm() {
+      // this.task.serviceType = ''
+      this.isModifyMode = true
+    },
+    //切换至不可编辑页面
+    cancelMode() {
+      this.isModifyMode = false
+    },
+    //重置表单
+    resetForm() {
+      this.task.name = ''
+      this.task.desc = ''
+      this.task.quotePrice = ''
+      this.task.fixedPrice = ''
+      this.task.type = ''
+      this.task.resource = '2' //如果是广场不用管Location和institution ,定向看institution,区域看location
+      this.task.location = {provinceCode: '', cityCode: ''}
+      this.task.institution = ''
+      this.task.datetime = ''
+      this.task.participantCount = 1
+      // this.task.endPointVO.caseId = ''
+      // this.task.endPointVO.examId = ''
+    },
+    //显示页面加载画面
+    showLoading() {
+      this.loading = true
+    },
+    //隐藏页面加载画面
+    hideLoading() {
+      this.loading = false
+    },
+    //加载用户信息
+    setUserInfo() {
+      this.user = storageGet('user')
+      this.rolesPermissions = storageGet('rolesPermissions')
+      if (storageGet('rolesPermissions').isRegionManager || storageGet('rolesPermissions').isSystemAdministrator) {
+        this.showBD = true;
+      } else {
+        this.showBD = false;
+      }
+    },
+    //加载任务的测试类型
+    setServiceType() {
+      getAllServiceTypes().then((res) => {
+        this.serviceType = res
+      }).catch((error) => {
+        notify('error', '加载测试类型失败')
+      })
+    },
+    //加载所有的测评机构
+    setInstitutions() {
+      getAllAgencies().then((res) => {
+        this.institutionArray = res
+      }).catch((error) => {
+        notify('error', '获取机构列表失败')
+      })
+    },
+    //获取任务详情
+    getTaskDetail() {
+      this.showLoading()
+      getTask(this.projectId, this.taskId, this.getTaskDetailSuccess, this.getTaskDetailFail)
+    },
+
+    //获取词云
+    getWordCloud(){
+      getTaskWordCloud(this.projectId, this.taskId, this.getTaskCloudSuccess, this.getTaskCloudFail)
+    },
+    getTaskCloudSuccess(words){
+      this.wordCloud = words.data;
+    },
+    getTaskCloudFail(err){
+      notify('error',err)
+    },
+
+    //获取任务详情成功时回调函数
+    getTaskDetailSuccess(res) {
+      this.hideLoading()
+      // console.log(res)
+      this.taskId = res.crowdTaskVO.id
+      this.projectId = res.crowdTaskVO.projectId
+      this.task.title = res.crowdTaskVO.title
+      this.task.description = res.crowdTaskVO.description
+      this.task.serviceType = res.crowdTaskVO.serviceType
+      this.task.resource = res.crowdTaskVO.resource.toString()
+      this.task.location = getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
+      this.task.institution = res.crowdTaskVO.institution
+      this.task.datetime = new Date(res.crowdTaskVO.datetime)
+      this.task.quotePrice = res.crowdTaskVO.quotePrice
+      this.task.acceptedCount = res.crowdTaskVO.acceptedCount
+      this.task.participantCount = res.crowdTaskVO.participantCount
+      this.task.fixedPrice = res.crowdTaskVO.fixedPrice
+      this.task.doc = []
+      this.task.requireDocUrl = res.crowdTaskVO.requirementFile
+      this.task.agencyId = res.crowdTaskVO.agencyId
+      this.task.status = res.crowdTaskVO.status
+      this.task.statusVO = res.crowdTaskVO.statusVO
+      this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
+        serverCode: '',
+      }
+      this.taskOperationControl = res.taskOperationControl;
+      this.acceptedUserList = res.acceptedUserList;
+      this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
+      this.handleFormatReport(this.acceptedUserList);
+      this.handleTestTypeChange(res.crowdTaskVO.serviceType);
+      this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType);
+      if(res.crowdTaskVO.endPointVO){
+        if(res.crowdTaskVO.endPointVO.token){
+          this.shortLink = res.crowdTaskVO.endPointVO.token;
+          this.editShortLink = false
+        }else{
+          this.editShortLink = true
         }
-        // console.log(res.crowdTaskVO.endPointVO.token)
-        // console.log(this.editShortLink)
-        // console.log(this.isModifyMode)
-      },
-      //获取任务详情失败时回调函数
-      getTaskDetailFail(error) {
-        this.hideLoading()
-        // notify('error', '获取任务详情失败:' + error.data)
-      },
+      }
+      // console.log(res.crowdTaskVO.endPointVO.token)
+      // console.log(this.editShortLink)
+      // console.log(this.isModifyMode)
+    },
+    //获取任务详情失败时回调函数
+    getTaskDetailFail(error) {
+      this.hideLoading()
+      // notify('error', '获取任务详情失败:' + error.data)
+    },
 
-      //处理显示报告
-      handleFormatReport(acceptedUserList) {
-        acceptedUserList.map((user) => {
-          user.crowdReportVOS && user.crowdReportVOS.map((report) => {
-            report.userName = user.userVO.userName;
-            this.reportList.push(report);
-          })
+    //处理显示报告
+    handleFormatReport(acceptedUserList) {
+      acceptedUserList.map((user) => {
+        user.crowdReportVOS && user.crowdReportVOS.map((report) => {
+          report.userName = user.userVO.userName;
+          this.reportList.push(report);
         })
-      },
+      })
+    },
 
-      dateFormat(date, format) {
-        date = new Date(date)
-        let o = {
-          'M+': date.getMonth() + 1, //month
-          'd+': date.getDate(), //day
-          'H+': date.getHours(), //hour+8小时
-          'm+': date.getMinutes(), //minute
-          's+': date.getSeconds(), //second
-          'q+': Math.floor((date.getMonth() + 3) / 3), //quarter
-          'S': date.getMilliseconds() //millisecond
-        }
-        if (/(y+)/.test(format)) {
-          format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
-        }
+    dateFormat(date, format) {
+      date = new Date(date)
+      let o = {
+        'M+': date.getMonth() + 1, //month
+        'd+': date.getDate(), //day
+        'H+': date.getHours(), //hour+8小时
+        'm+': date.getMinutes(), //minute
+        's+': date.getSeconds(), //second
+        'q+': Math.floor((date.getMonth() + 3) / 3), //quarter
+        'S': date.getMilliseconds() //millisecond
+      }
+      if (/(y+)/.test(format)) {
+        format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
+      }
 
-        for (let k in o)
-          if (new RegExp('(' + k + ')').test(format))
-            format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
+      for (let k in o)
+        if (new RegExp('(' + k + ')').test(format))
+          format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
 
-        return format;
-      },
+      return format;
+    },
 
-      //更新任务信息
-      updateTask() {
-        this.$refs['task'].validate(valid => {
-          if (valid) {
-            this.showLoading()
-            const newTask = {
-              name: this.task.title,
-              desc: this.task.description,
-              type: this.task.serviceType,
-              resource: this.task.resource,
-              location: this.task.location == null ? {} : getProvinceNameByProvinceCode(this.task.location.provinceCode, this.task.location.cityCode),
-              institution: this.task.institution ? this.task.institution.id : null,
-              datetime: this.task.datetime,
-              quotePrice: this.task.quotePrice,
-              fixedPrice: this.task.fixedPrice,
-              requirementFile: this.task.requireDocUrl,
-              participantCount: this.task.participantCount,
-              endPoint: this.task.endPoint
-            }
-            //console.log(newTask)
-            updateTask(this.projectId, this.taskId, newTask, this.updateTaskSuccess, this.updateTaskFail)
-          } else {
-            notify('error', '表单填写有误!')
-            return false
-          }
-        })
-      },
-      //更新任务信息成功时回调函数
-      updateTaskSuccess(res) {
-        this.cancelMode()
-        this.taskId = res.crowdTaskVO.id
-        this.projectId = res.crowdTaskVO.projectId
-        this.task.title = res.crowdTaskVO.title
-        this.task.description = res.crowdTaskVO.description
-        this.task.serviceType = res.crowdTaskVO.serviceType
-        this.task.resource = res.crowdTaskVO.resource
-        this.task.location = res.crowdTaskVO.location == null ? {
-          provinceCode: 3200,
-          cityCode: 3201
-        } : getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
-        this.task.institution = res.crowdTaskVO.institution
-        this.task.datetime = new Date(res.crowdTaskVO.datetime)
-        this.task.quotePrice = res.crowdTaskVO.quotePrice
-        this.task.fixedPrice = res.crowdTaskVO.fixedPrice
-        // this.task.endPointVO = res.crowdTaskVO.endPointVO
-        this.task.doc = []
-        this.task.requireDocUrl = res.crowdTaskVO.requirementFile,
-          this.task.participantCount = res.crowdTaskVO.participantCount
-          this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
-            serverCode: '',
+    //更新任务信息
+    updateTask() {
+      this.$refs['task'].validate(valid => {
+        if (valid) {
+          this.showLoading()
+          const newTask = {
+            name: this.task.title,
+            desc: this.task.description,
+            type: this.task.serviceType,
+            resource: this.task.resource,
+            location: this.task.location == null ? {} : getProvinceNameByProvinceCode(this.task.location.provinceCode, this.task.location.cityCode),
+            institution: this.task.institution ? this.task.institution.id : null,
+            datetime: this.task.datetime,
+            quotePrice: this.task.quotePrice,
+            fixedPrice: this.task.fixedPrice,
+            requirementFile: this.task.requireDocUrl,
+            participantCount: this.task.participantCount,
+            endPoint: this.task.endPoint
           }
-        this.reportList = res.crowdReportVOList
-        this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
-        this.acceptedUserList = res.acceptedUserList
-        this.handleTestTypeChange(res.crowdTaskVO.serviceType);
-        this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType);
-        this.hideLoading()
-        notify('success', '修改成功')
-      },
-      //更新任务信息失败时回调函数
-      updateTaskFail(error) {
-        notify('error', '修改失败:' + error.data)
-        this.hideLoading()
-      },
-      //上传任务需求文档
-      uploadRequireDoc(param) {
-        const formData = new FormData()
-        let config = {
-          //添加请求头
-          headers: {'Content-Type': 'multipart/form-data'},
+          //console.log(newTask)
+          updateTask(this.projectId, this.taskId, newTask, this.updateTaskSuccess, this.updateTaskFail)
+        } else {
+          notify('error', '表单填写有误!')
+          return false
         }
-        formData.append('file', param.file)
-        Http.upload(Apis.FILE.REQUIREMENT_FILE.replace('{userId}', this.user.userVO.id), formData, config).then((res) => {
-          notify('success', '上传成功')
-          this.uploadRequireDocSuccess(res)
-        }).catch((error) => {
-          notify('error', '上传失败:' + error.data)
-          this.uploadRequireDocFail(error)
-        })
-      },
-      //上传任务需求文档成功时回调函数
-      uploadRequireDocSuccess(res) {
-        this.hideLoading()
-        console.log('上传成功')
-        this.task.requireDocUrl = res.data
-        console.log(res.data)
-      },
-      //上传任务需求文档失败时回调函数
-      uploadRequireDocFail(error) {
-        this.hideLoading()
-        notify('error', '任务需求文档上传失败:' + error.data)
-      },
-      //文档上传前响应函数
+      })
+    },
+    //更新任务信息成功时回调函数
+    updateTaskSuccess(res) {
+      this.cancelMode()
+      this.taskId = res.crowdTaskVO.id
+      this.projectId = res.crowdTaskVO.projectId
+      this.task.title = res.crowdTaskVO.title
+      this.task.description = res.crowdTaskVO.description
+      this.task.serviceType = res.crowdTaskVO.serviceType
+      this.task.resource = res.crowdTaskVO.resource
+      this.task.location = res.crowdTaskVO.location == null ? {
+        provinceCode: 3200,
+        cityCode: 3201
+      } : getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
+      this.task.institution = res.crowdTaskVO.institution
+      this.task.datetime = new Date(res.crowdTaskVO.datetime)
+      this.task.quotePrice = res.crowdTaskVO.quotePrice
+      this.task.fixedPrice = res.crowdTaskVO.fixedPrice
+      // this.task.endPointVO = res.crowdTaskVO.endPointVO
+      this.task.doc = []
+      this.task.requireDocUrl = res.crowdTaskVO.requirementFile,
+        this.task.participantCount = res.crowdTaskVO.participantCount
+      this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
+        serverCode: '',
+      }
+      this.task.createTime = res.crowdTaskVO.createTime,
+        this.reportList = res.crowdReportVOList
+      this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
+      this.acceptedUserList = res.acceptedUserList
+      this.handleTestTypeChange(res.crowdTaskVO.serviceType);
+      this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType);
+      this.hideLoading()
+      notify('success', '修改成功')
+    },
+    //更新任务信息失败时回调函数
+    updateTaskFail(error) {
+      notify('error', '修改失败:' + error.data)
+      this.hideLoading()
+    },
+    //上传任务需求文档
+    uploadRequireDoc(param) {
+      const formData = new FormData()
+      let config = {
+        //添加请求头
+        headers: {'Content-Type': 'multipart/form-data'},
+      }
+      formData.append('file', param.file)
+      Http.upload(Apis.FILE.REQUIREMENT_FILE.replace('{userId}', this.user.userVO.id), formData, config).then((res) => {
+        notify('success', '上传成功')
+        this.uploadRequireDocSuccess(res)
+      }).catch((error) => {
+        notify('error', '上传失败:' + error.data)
+        this.uploadRequireDocFail(error)
+      })
+    },
+    //上传任务需求文档成功时回调函数
+    uploadRequireDocSuccess(res) {
+      this.hideLoading()
+      console.log('上传成功')
+      this.task.requireDocUrl = res.data
+      console.log(res.data)
+    },
+    //上传任务需求文档失败时回调函数
+    uploadRequireDocFail(error) {
+      this.hideLoading()
+      notify('error', '任务需求文档上传失败:' + error.data)
+    },
+    //文档上传前响应函数
 
-      //移除文档前的响应函数
-      beforeRemove(file, fileList) {
-        //return this.$confirm(`确定移除 ${file.name}?`)
-      },
-      //移除文档时的响应函数
-      handleRemove(file, fileList) {
-        console.log(file, fileList)
-      },
-      //需求文档添加进来时的响应函数
-      handleExceed(files, fileList) {
-        this.$message.warning(
-          `当前限制选择 1 个文件,本次选择了 ${
-            files.length
-            } 个文件,共选择了 ${files.length + fileList.length} 个文件`
-        )
-      },
-      //接收任务
-      receiveTask() {
-        this.$confirm('确认接收任务?', '提示', {
-          confirmButtonText: '确认接收',
-          cancelButtonText: '取消',
-          type: 'success'
-        }).then(() => {
-          this.showLoading()
-          receiveTaskRequest(this.projectId, this.taskId, this.user.userVO.id, this.receiveTaskSuccess, this.receiveTaskFail)
-        }).catch(() => {
-        })
-      },
-      //接收任务成功时的回调函数
-      receiveTaskSuccess(res) {
-        this.hideLoading()
-        this.getTaskDetail();
-        notify('success', '接收任务成功')
-        // console.log(res)
-        this.taskOperationControl = res.taskOperationControl
-        this.task.status = res.crowdTaskVO.status
-        this.task.institution = res.crowdTaskVO.institution
-      },
-      //接收任务失败时的回调函数
-      receiveTaskFail(error) {
-        this.hideLoading()
-        notify('error', '接收任务失败:' + error.data)
-      },
-      //拒绝任务
-      rejectTask() {
-        this.$confirm('确认拒绝任务?拒绝后将不能再接收该任务', '提示', {
-          confirmButtonText: '确认拒绝',
-          cancelButtonText: '取消',
-          type: 'success'
-        }).then(() => {
-          this.showLoading()
-          rejectTask(this.projectId, this.taskId, this.rejectTaskSuccess, this.rejectTaskFail)
-        }).catch(() => {
+    //移除文档前的响应函数
+    beforeRemove(file, fileList) {
+      //return this.$confirm(`确定移除 ${file.name}?`)
+    },
+    //移除文档时的响应函数
+    handleRemove(file, fileList) {
+      console.log(file, fileList)
+    },
+    //需求文档添加进来时的响应函数
+    handleExceed(files, fileList) {
+      this.$message.warning(
+        `当前限制选择 1 个文件,本次选择了 ${
+          files.length
+        } 个文件,共选择了 ${files.length + fileList.length} 个文件`
+      )
+    },
+    //接收任务
+    receiveTask() {
+      this.$confirm('确认接收任务?', '提示', {
+        confirmButtonText: '确认接收',
+        cancelButtonText: '取消',
+        type: 'success'
+      }).then(() => {
+        this.showLoading()
+        receiveTaskRequest(this.projectId, this.taskId, this.user.userVO.id, this.receiveTaskSuccess, this.receiveTaskFail)
+      }).catch(() => {
+      })
+    },
+    //接收任务成功时的回调函数
+    receiveTaskSuccess(res) {
+      this.hideLoading()
+      this.getTaskDetail();
+      notify('success', '接收任务成功')
+      // console.log(res)
+      this.taskOperationControl = res.taskOperationControl
+      this.task.status = res.crowdTaskVO.status
+      this.task.institution = res.crowdTaskVO.institution
+    },
+    //接收任务失败时的回调函数
+    receiveTaskFail(error) {
+      this.hideLoading()
+      notify('error', '接收任务失败:' + error.data)
+    },
 
-        })
-      },
-      //拒绝任务成功时的回调函数
-      rejectTaskSuccess(res) {
-        this.hideLoading()
-        this.$router.push({
-          name: 'Mine'
-        })
-        notify('success', '拒绝任务成功,已为您自动跳转到个人中心')
-      },
-      //拒绝任务失败时的回调函数
-      rejectTaskFail(error) {
-        this.hideLoading()
-        notify('error', '拒绝任务失败:' + error.data)
-      },
-      //提交结束任务申请
-      submitTaskRequest() {
-        this.$confirm('确认提交任务?提交后将不能再修改', '提示', {
-          confirmButtonText: '确认提交',
-          cancelButtonText: '取消',
-          type: 'success'
-        }).then(() => {
-          this.showLoading()
-          submitTaskRequest(this.projectId, this.taskId, this.submitTaskRequestSuccess, this.submitTaskRequestFail)
+    // 任务推荐
+    recommendTask(){
+      let task = {
+        "title": this.task.title,
+        "description": this.task.description,
+        "participantCount": this.task.participantCount,
+        "quotePrice": this.task.quotePrice,
+        "requirementFile": this.task.requireDocUrl,
+        "serviceType": this.task.serviceType,
+        "createTime": this.task.createTime,
+        "datetime": this.task.datetime
+      };
+      Http.post('/recommendationtest/querywithparam',task).then((res)=>{
+        window.open('http://59.42.10.54:7477/userinformation.html');
+      })
+    },
 
-        }).catch(() => {
+    //拒绝任务
+    rejectTask() {
+      this.$confirm('确认拒绝任务?拒绝后将不能再接收该任务', '提示', {
+        confirmButtonText: '确认拒绝',
+        cancelButtonText: '取消',
+        type: 'success'
+      }).then(() => {
+        this.showLoading()
+        rejectTask(this.projectId, this.taskId, this.rejectTaskSuccess, this.rejectTaskFail)
+      }).catch(() => {
 
-        })
-      },
-      //提交结束任务申请成功时的回调函数
-      submitTaskRequestSuccess(res) {
-        this.hideLoading()
-        console.log(res)
-        this.taskOperationControl = res.taskOperationControl
-        this.task.status = res.crowdTaskVO.status
-        this.task.institution = res.crowdTaskVO.institution
-        notify('success', '提交任务成功,等待区域管理员审核')
-        this.getTaskDetail();
-      },
-      //提交结束任务申请失败时的回调函数
-      submitTaskRequestFail(error) {
-        this.hideLoading()
-        notify('error', '提交任务失败:' + error.data)
-      },
-      //结束任务
-      endTask() {
-        this.$confirm('确认结束任务?', '提示', {
-          confirmButtonText: '确认结束',
-          cancelButtonText: '取消',
-          type: 'success'
-        }).then(() => {
-          this.getTaskDetail()
-          this.showLoading()
-          ensureEndTask(this.projectId, this.taskId, this.endTaskSuccess, this.endTaskFail)
-        }).catch(() => {
+      })
+    },
+    //拒绝任务成功时的回调函数
+    rejectTaskSuccess(res) {
+      this.hideLoading()
+      this.$router.push({
+        name: 'Mine'
+      })
+      notify('success', '拒绝任务成功,已为您自动跳转到个人中心')
+    },
+    //拒绝任务失败时的回调函数
+    rejectTaskFail(error) {
+      this.hideLoading()
+      notify('error', '拒绝任务失败:' + error.data)
+    },
+    //提交结束任务申请
+    submitTaskRequest() {
+      this.$confirm('确认提交任务?提交后将不能再修改', '提示', {
+        confirmButtonText: '确认提交',
+        cancelButtonText: '取消',
+        type: 'success'
+      }).then(() => {
+        this.showLoading()
+        submitTaskRequest(this.projectId, this.taskId, this.submitTaskRequestSuccess, this.submitTaskRequestFail)
 
-        })
-      },
-      //结束任务成功时的回调函数
-      endTaskSuccess(res) {
-        this.hideLoading()
-        this.taskOperationControl = res.taskOperationControl
-        this.task.status = res.crowdTaskVO.status
-        this.task.institution = res.crowdTaskVO.institution
-        notify('success', '结束任务成功!')
-        this.getTaskDetail();
-      },
-      //结束任务失败时的回调函数
-      endTaskFail(error) {
-        this.hideLoading()
-        notify('error', '结束任务失败:' + error.data)
-      },
-      //跳转到创建项目报告页面
-      toCreateReport() {
-        this.$router.push({
-          name: 'TaskReportCreate',
-          params: {
-            scope: 1,
-            dependencyCode: this.taskId,
-            projectId: this.projectId,
-            taskId: this.taskId,
-          }
-        })
-      },
-      reformDate(date) {
-        return getFormalTimeFromDate(date)
-      }
+      }).catch(() => {
+
+      })
+    },
+    //提交结束任务申请成功时的回调函数
+    submitTaskRequestSuccess(res) {
+      this.hideLoading()
+      console.log(res)
+      this.taskOperationControl = res.taskOperationControl
+      this.task.status = res.crowdTaskVO.status
+      this.task.institution = res.crowdTaskVO.institution
+      notify('success', '提交任务成功,等待区域管理员审核')
+      this.getTaskDetail();
+    },
+    //提交结束任务申请失败时的回调函数
+    submitTaskRequestFail(error) {
+      this.hideLoading()
+      notify('error', '提交任务失败:' + error.data)
+    },
+    //结束任务
+    endTask() {
+      this.$confirm('确认结束任务?', '提示', {
+        confirmButtonText: '确认结束',
+        cancelButtonText: '取消',
+        type: 'success'
+      }).then(() => {
+        this.getTaskDetail()
+        this.showLoading()
+        ensureEndTask(this.projectId, this.taskId, this.endTaskSuccess, this.endTaskFail)
+      }).catch(() => {
+
+      })
+    },
+    //结束任务成功时的回调函数
+    endTaskSuccess(res) {
+      this.hideLoading()
+      this.taskOperationControl = res.taskOperationControl
+      this.task.status = res.crowdTaskVO.status
+      this.task.institution = res.crowdTaskVO.institution
+      notify('success', '结束任务成功!')
+      this.getTaskDetail();
+    },
+    //结束任务失败时的回调函数
+    endTaskFail(error) {
+      this.hideLoading()
+      notify('error', '结束任务失败:' + error.data)
+    },
+    //跳转到创建项目报告页面
+    toCreateReport() {
+      this.$router.push({
+        name: 'TaskReportCreate',
+        params: {
+          scope: 1,
+          dependencyCode: this.taskId,
+          projectId: this.projectId,
+          taskId: this.taskId,
+        }
+      })
     },
-  }
-  //回收站
-  //
-  // updateLocation (location) {
-  //   console.log(location)
-  //   const loactionName = getProvinceNameByProvinceCode(location.provinceCode, location.cityCode)
-  //   // var provinceName = ''
-  //   // var cityName = ''
-  //   // for (var item of provinceCityJSON.provinces) {
-  //   //   if (item.code === location.provinceCode) {
-  //   //     provinceName = item.name
-  //   //     for (var city of item.cities) {
-  //   //       if (city.code === location.cityCode) {
-  //   //         cityName = city.name
-  //   //         break
-  //   //       }
-  //   //     }
-  //   //   }
-  //   // }
-  //   return loactionName.provinceCode + ' / ' + loactionName.cityCode
-  // },
-  //
-  // locationChange (provinceId, cityId) {
-  //   if (provinceId || cityId) {
-  //     this.task.location = {provinceCode: provinceId, cityCode: cityId}
-  //   }
-  // },
-  // submitForm (formName) {
-  // this.$refs[formName].validate(valid => {
-  //   if (valid) {
-  //     this.isModifyMode = false
-  //
-  //   } else {
-  //     console.log('error submit!!')
-  //     return false
-  //   }
-  // })
-  // },
+    reformDate(date) {
+      return getFormalTimeFromDate(date)
+    }
+  },
+}
+//回收站
+//
+// updateLocation (location) {
+//   console.log(location)
+//   const loactionName = getProvinceNameByProvinceCode(location.provinceCode, location.cityCode)
+//   // var provinceName = ''
+//   // var cityName = ''
+//   // for (var item of provinceCityJSON.provinces) {
+//   //   if (item.code === location.provinceCode) {
+//   //     provinceName = item.name
+//   //     for (var city of item.cities) {
+//   //       if (city.code === location.cityCode) {
+//   //         cityName = city.name
+//   //         break
+//   //       }
+//   //     }
+//   //   }
+//   // }
+//   return loactionName.provinceCode + ' / ' + loactionName.cityCode
+// },
+//
+// locationChange (provinceId, cityId) {
+//   if (provinceId || cityId) {
+//     this.task.location = {provinceCode: provinceId, cityCode: cityId}
+//   }
+// },
+// submitForm (formName) {
+// this.$refs[formName].validate(valid => {
+//   if (valid) {
+//     this.isModifyMode = false
+//
+//   } else {
+//     console.log('error submit!!')
+//     return false
+//   }
+// })
+// },
 </script>
 
-<style lang="scss" scoped>
-  .el-radio {
-    margin: 10px 20px 10px 0;
-  }
+<style lang="less" scoped>
+.el-radio {
+  margin: 10px 20px 10px 0;
+}
 
-  .el-form-item /deep/ .el-tabs__content {
-    /*max-height: 120px !important;*/
-    overflow: auto;
-  }
+.el-form-item /deep/ .el-tabs__content {
+  /*max-height: 120px !important;*/
+  overflow: auto;
+}
 
-  .el-collapse-item__content {
-    padding-bottom: 0 !important;
-  }
+.el-collapse-item__content {
+  padding-bottom: 0 !important;
+}
 </style>

+ 106 - 0
src/components/task/TaskCloud.vue

@@ -0,0 +1,106 @@
+<template>
+  <div id='taskWordCloud' style="height: 457px;width: 100%" ></div>
+</template>
+
+<script>
+import echarts from "echarts";
+// import resize from "./mixins/resize";
+import "echarts-wordcloud/dist/echarts-wordcloud";
+import "echarts-wordcloud/dist/echarts-wordcloud.min";
+
+export default {
+  name: "TaskCloud",
+  // mixins: [resize],
+  props: ['info'],
+  data() {
+    return {
+      chart: null
+    };
+  },
+  mounted() {
+    this.initChart();
+  },
+  beforeDestroy() {
+    if (!this.chart) {
+      return;
+    }
+    this.chart.dispose();
+    this.chart = null;
+  },
+  methods: {
+    initChart() {
+      this.chart = echarts.init(document.getElementById('taskWordCloud'),{width:'auto',height:'500px'});
+      const option = {
+        backgroundColor: "#fff",
+        // tooltip: {
+        //   pointFormat: "{series.name}: <b>{point.percentage:.1f}%</b>"
+        // },
+        series: [
+          {
+            type: "wordCloud",
+            //用来调整词之间的距离
+            gridSize: 10,
+            //用来调整字的大小范围
+            // Text size range which the value in data will be mapped to.
+            // Default to have minimum 12px and maximum 60px size.
+            sizeRange: [14, 60],
+            // Text rotation range and step in degree. Text will be rotated randomly in range [-90,                                                                             90] by rotationStep 45
+            //用来调整词的旋转方向,,[0,0]--代表着没有角度,也就是词为水平方向,需要设置角度参考注释内容
+            // rotationRange: [-45, 0, 45, 90],
+            // rotationRange: [ 0,90],
+            rotationRange: [0, 0],
+            //随机生成字体颜色
+            // maskImage: maskImage,
+            textStyle: {
+              normal: {
+                color: function() {
+                  return (
+                    "rgb(" +
+                    Math.round(Math.random() * 255) +
+                    ", " +
+                    Math.round(Math.random() * 255) +
+                    ", " +
+                    Math.round(Math.random() * 255) +
+                    ")"
+                  );
+                }
+              }
+            },
+            grid:{
+              x:10,
+              y:10,
+              x2:10,
+              y2:10,
+              height:"500px",
+              width:"100%"
+            },
+            //位置相关设置
+            // Folllowing left/top/width/height/right/bottom are used for positioning the word cloud
+            // Default to be put in the center and has 75% x 80% size.
+            left: 0,
+            top: 0,
+            right: 0,
+            bottom: 0,
+            width: "100%",
+            height: "100%",
+            //数据
+            data: this.info
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+}
+</script>
+
+<style lang='scss' scoped>
+.chartsClass {
+  padding-left: 1.2rem;
+}
+
+#userWordCloud {
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+</style>
+

+ 1 - 1
src/components/task/TaskCreate.vue

@@ -190,7 +190,7 @@
           type: [
             {required: true, message: '测试类型不可为空'},
           ],
-          desc: [{required: false, message: '请填写描述', trigger: 'blur'}],
+          desc: [{required: true, message: '请填写描述', trigger: 'blur'}],
           //price: [{required: true, message: '请填写价格', trigger: 'blur'}],
           quotePrice: [
             {required: true, message: '预算不可为空', trigger: 'blur'},

+ 55 - 0
src/components/task/mixins/resize.js

@@ -0,0 +1,55 @@
+import { debounce } from '@/utils'
+
+export default {
+  data() {
+    return {
+      $_sidebarElm: null,
+      $_resizeHandler: null
+    }
+  },
+  mounted() {
+    this.$_resizeHandler = debounce(() => {
+      if (this.chart) {
+        this.chart.resize()
+      }
+    }, 100)
+    this.$_initResizeEvent()
+    this.$_initSidebarResizeEvent()
+  },
+  beforeDestroy() {
+    this.$_destroyResizeEvent()
+    this.$_destroySidebarResizeEvent()
+  },
+  // to fixed bug when cached by keep-alive
+  // https://github.com/PanJiaChen/vue-element-admin/issues/2116
+  activated() {
+    this.$_initResizeEvent()
+    this.$_initSidebarResizeEvent()
+  },
+  deactivated() {
+    this.$_destroyResizeEvent()
+    this.$_destroySidebarResizeEvent()
+  },
+  methods: {
+    // use $_ for mixins properties
+    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+    $_initResizeEvent() {
+      window.addEventListener('resize', this.$_resizeHandler)
+    },
+    $_destroyResizeEvent() {
+      window.removeEventListener('resize', this.$_resizeHandler)
+    },
+    $_sidebarResizeHandler(e) {
+      if (e.propertyName === 'width') {
+        this.$_resizeHandler()
+      }
+    },
+    $_initSidebarResizeEvent() {
+      this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
+      this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
+    },
+    $_destroySidebarResizeEvent() {
+      this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
+    }
+  }
+}

+ 3 - 0
src/config/index.js

@@ -133,3 +133,6 @@ export let CONFIG = {};
 export const setConfig = (conf) => {
   CONFIG = conf;
 }
+
+export const login_url = '/page/login?redirect=http%3a%2f%2fcrowd.dev.mooctest.net%2f%23%2fhome'
+export const  register_url = '/page/register'

+ 1 - 0
src/js/api.js

@@ -24,6 +24,7 @@ export default {
     SUBMIT_TASK: '/api/project/{projectId}/task/{taskId}/status/commit',
     END_TASK: '/api/project/{projectId}/task/{taskId}/status/finished',
     MORE_HOT_TASK: '/api/square/hotTasks/list',
+    GET_TASK_CLOUD:'/api/project/{projectId}/task/{taskId}/word'
   },
   REPORT: {
     GET_TASK_REPORT: '/api/project/{projectId}/task/{taskId}/report/{reportId}/',

+ 1 - 1
src/js/http.js

@@ -36,7 +36,7 @@ function handleResults (response) {
 }
 
 function handleUrl (url) {
-  return BASE_URL + url
+  return url
 }
 
 /*

+ 3 - 1
src/js/index.js

@@ -39,7 +39,8 @@ import {
   receiveTaskRequest,
   rejectTask,
   submitTaskRequest,
-  updateTask
+  updateTask,
+  getTaskWordCloud
 } from './taskService'
 import {
   createProjectReport,
@@ -152,6 +153,7 @@ export {
   submitTaskRequest,
   //区域管理员修改任务
   updateTask,
+  getTaskWordCloud
 }
 export {
   /*******************************************************************************/

+ 9 - 0
src/js/taskService.js

@@ -23,6 +23,15 @@ export const getTask = (projectId, taskId, getTaskSuccess, getTaskFail) => {
   })
 }
 
+//查看词云
+export const getTaskWordCloud = (projectId, taskId,getSuccess) => {
+  Http.get(Apis.TASK.GET_TASK_CLOUD.replace('{projectId}', projectId).replace('{taskId}', taskId), {}).then((res)=>{
+    getSuccess(res)
+  }).catch(err=>{
+    console.log(err)
+  })
+}
+
 //删除任务
 export const deleteTask = (projectId, taskId, deleteTaskSuccess, deleteTaskFail) => {
   Http.put(Apis.TASK.DELETE_TASK.replace('{projectId}', projectId).replace('taskId', taskId), {}).then((res) => {

+ 0 - 0
src/js/test.js


+ 7 - 7
src/main.js

@@ -12,6 +12,7 @@ import moment from 'moment'
 import vRegion from 'v-region'
 import echarts from "echarts";
 import Http from '@/js/http.js'
+import {configToJson} from './utils/filters'
 import {
   Avatar,
   Alert,
@@ -209,13 +210,11 @@ Vue.config.productionTip = false
 
 
 Http.get('/api/common/configuration').then((res) => {
-  this.homeDataNoCache = res.data;
-  // console.log(res.data.configurationList.configuration);
-  // console.log(JSON.parse(res.data.configurationList.configuration));
-  // console.log(JSON.parse(res.data.configurationList.configuration).home_searchTypeArr);
-  let config = JSON.parse(res.data.configurationList.configuration);
-  setConfig(config);
-  storageSave('config', config);
+  let config = res.data&&res.data.configurationList;
+  let configData = configToJson(config);
+  this.homeDataNoCache = configData;
+  setConfig(configData);
+  storageSave('config', configData);
   new Vue({
     el: '#app',
     router,
@@ -227,6 +226,7 @@ Http.get('/api/common/configuration').then((res) => {
     store
   })
 }).catch((error) => {
+  console.log(error)
   notify('error', error.data)
 })
 

+ 11 - 10
src/pages/Homepage/Homepage.vue

@@ -5,7 +5,7 @@
       <el-row class="search-nav" style="padding: 30px 0 20px 0">
         <el-col :span="6">
           <div class="pull-left">
-            <img class="logo-img" :src="require('../../assets/image/' + logo_transparent)" :to="'/home'"/>
+            <img class="logo-img" :src="logo_transparent" :to="'/home'"/>
             <span class="logo-title">{{ logoTitle }}</span>
           </div>
         </el-col>
@@ -43,24 +43,25 @@
     </div>
 
     <div class="home-page container">
-      <el-row>
+      <el-row :gutter="15">
+        <el-col :span="5" class="homepage-right-modules">
+          <LoginCard v-if="HOME_DISPLAY.login_card"/>
+          <HotCrowd :applicationTypeRank="homeDataNoCache.applicationTypeRank" v-if="HOME_DISPLAY.hot_crowd"/>
+          <HotAgency :agencyRank="homeDataNoCache.agencyRank" v-if="HOME_DISPLAY.hot_agency"/>
+          <HotUser :userRank="homeDataNoCache.userRank" v-if="HOME_DISPLAY.hot_user"/>
+          <HotContest :competitionList="homeData.competitionList" v-if="HOME_DISPLAY.hot_contest"/>
+        </el-col>
+
         <el-col :span="19" class="test-type-wrapper">
           <TestMenu :testTypeList="homeData.testTypeList" v-if="HOME_DISPLAY.test_menu"></TestMenu>
           <TestCard :applicationTypeList="homeData.applicationTypeList" v-if="HOME_DISPLAY.test_card"></TestCard>
           <el-row style="margin-top: 10px" v-if="HOME_DISPLAY.resource_and_tool">
-            <ResourceAndTool :resourceList="homeDataNoCache.resourceList"></ResourceAndTool>
+            <ResourceAndTool :resourceList="homeDataNoCache.toolList"></ResourceAndTool>
           </el-row>
           <el-row v-if="HOME_DISPLAY.brand_card">
             <BrandCard :residentAgencyList=homeData.residentAgencyList></BrandCard>
           </el-row>
         </el-col>
-        <el-col :span="5" class="homepage-right-modules">
-          <LoginCard v-if="HOME_DISPLAY.login_card"/>
-          <HotCrowd :applicationTypeRank="homeDataNoCache.applicationTypeRank" v-if="HOME_DISPLAY.hot_crowd"/>
-          <HotAgency :agencyRank="homeDataNoCache.agencyRank" v-if="HOME_DISPLAY.hot_agency"/>
-          <HotUser :userRank="homeDataNoCache.userRank" v-if="HOME_DISPLAY.hot_user"/>
-          <HotContest :competitionList="homeData.competitionList" v-if="HOME_DISPLAY.hot_contest"/>
-        </el-col>
       </el-row>
       <InstitutionCard v-if="HOME_DISPLAY.institution_card"></InstitutionCard>
     </div>

+ 1 - 1
src/pages/Homepage/HotContest.vue

@@ -8,7 +8,7 @@
     <div class="popular-list">
       <el-row class="popular-list-item" v-for="item in competitionList" :key="item.id">
         <el-col :span="23" @click.native="gotoDetail(item)">
-          <img :src="require('../../assets/image/' + logo_background)" alt="logo-project" class="pull-left project-logo-img">
+          <img :src="logo_background" alt="logo-project" class="pull-left project-logo-img">
           <div style="margin-left: 55px">
             <div class="list-item-title">
               {{item.name}}

+ 3 - 3
src/pages/Homepage/LoginCard.vue

@@ -1,7 +1,7 @@
 <template>
   <el-card class="login-card">
     <div class="login-welcome">
-      <img :src="!this.userImg?require('../../assets/image/' + logo_background):this.userImg" alt="welcome-img"
+      <img :src="!this.userImg?logo_background:this.userImg" alt="welcome-img"
            class="pull-left welcome-img">
       <div style="margin-left: 46px">
         <div class="welcome-title">
@@ -27,7 +27,7 @@
   import Http from '@/js/http.js'
   import {logout, storageGet} from '@/js/index.js'
   import {mapActions,mapGetters} from 'vuex'
-  import {CONFIG} from "../../config";
+  import {CONFIG,login_url} from "../../config";
 
   export default {
     name: "LoginCard",
@@ -37,7 +37,7 @@
         logo_background:CONFIG.logo_background,
         isLogin: false,
         user: {},
-        loginUrl: process.env.LOGIN_URL,
+        loginUrl: login_url,
         userImg: ''
       }
     },

+ 8 - 9
src/pages/Homepage/ResourceAndTool.vue

@@ -1,13 +1,13 @@
 <template>
   <el-card class="test-card">
     <div slot="header" class="clearfix test-card-header">
-      <span>众测资源</span>
+      <span>众测工具</span>
       <el-button style="float: right; padding: 3px 0;line-height: 25px" type="text"  @click="getMore()">more>></el-button>
     </div>
     <div>
       <el-row>
         <el-col :span="8" v-for="item in resourceList" :key="item.code" style=" margin-bottom: 10px;">
-          <span style="cursor: pointer; font-size: 18px;" @click="goToDetail(item.code)">{{item.name}}</span>
+          <span style="cursor: pointer; font-size: 18px;" @click="goToDetail(item)">{{item.name}}</span>
         </el-col>
       </el-row>
     </div>
@@ -15,21 +15,20 @@
 </template>
 
 <script>
+  import {CONFIG} from "../../config";
+  import Http from '@/js/http.js'
+
   export default {
     name: "ResourceAndTool",
     props:['resourceList'],
     methods:{
         getMore(){
             this.$router.push({
-                name: 'ResourceList',
+                path: '/technology',
             });
         },
-        goToDetail(code) {
-            this.$router.push({
-                name: 'ResourceDetail',
-                path:'/resource/detail',
-                query: {id: code}
-            })
+        goToDetail(item) {
+            window.open(item.linkUrl)
         },
     }
   }

+ 40 - 65
src/pages/Homepage/TestCard.vue

@@ -1,79 +1,54 @@
 <template>
-  <div class="card-waterfull">
-    <el-row :gutter="20">
-      <waterfall
-        :line-gap="400"
-        :min-line-gap="150"
-        :max-line-gap="200"
-        :single-max-width="400"
-        :watch="applicationTypeList">
-        <!-- each component is wrapped by a waterfall slot -->
-
-        <waterfall-slot
-          v-for="(item, index) in applicationTypeList"
-          width="310"
-          :height="200"
-          :order="index"
-          :key="item.code"
-        >
-          <el-card class="test-card" :body-style="{width:'300'}">
-            <div slot="header" class="clearfix test-card-header">
-              <span>{{item.name}}</span>
-            </div>
-            <div>
-              <span>{{item.introduction}}</span>
-            </div>
-          </el-card>
-        </waterfall-slot>
-      </waterfall>
-    </el-row>
-  </div>
+  <el-row :gutter="20">
+    <el-col :span="8" v-for="item in applicationTypeList" :key="item.name" style="height: 160px;margin-bottom: 10px">
+      <el-card class="test-card">
+        <div slot="header" class="clearfix test-card-header">
+          <span>{{ item && item.name }}</span>
+        </div>
+        <div>
+          <span>{{ item && item.introduction }}</span>
+        </div>
+      </el-card>
+    </el-col>
+  </el-row>
 </template>
 
 <script>
-  import Waterfall from 'vue-waterfall/lib/waterfall'
-  import WaterfallSlot from 'vue-waterfall/lib/waterfall-slot'
-
-  export default {
-    name: "TestCard",
-    props: ['applicationTypeList'],
-    data() {
-      return {}
-    },
-    components: {
-      Waterfall,
-      WaterfallSlot
-    },
-    methods: {},
-    mounted() {}
+// import Waterfall from 'vue-waterfall/lib/waterfall'
+// import WaterfallSlot from 'vue-waterfall/lib/waterfall-slot'
+
+export default {
+  name: "TestCard",
+  props: ['applicationTypeList'],
+  data() {
+    return {}
+  },
+  components: {
+    // Waterfall,
+    // WaterfallSlot
+  },
+  methods: {},
+  mounted() {
   }
+}
 </script>
 
 <style lang="scss">
-  @import "../../style/main";
-
-  .test-card {
-    border: none;
+@import "../../style/main";
 
-    .el-card__header {
-      height: 48px !important;
-      background: $__color-primary-background !important;
-      padding: 12px 15px !important;
-    }
+.test-card {
+  border: none;
 
-    .test-card-header {
-      border-left: 5px solid $__color-primary;
-      padding-left: 5px;
-    }
+  .el-card__header {
+    height: 48px !important;
+    background: $__color-primary-background !important;
+    padding: 12px 15px !important;
   }
 
-  .card-waterfull {
-    .el-card {
-      width: 98% !important;
-    }
-
-    .el-row {
-      margin: 0 !important;
-    }
+  .test-card-header {
+    border-left: 5px solid $__color-primary;
+    padding-left: 5px;
   }
+}
+
 </style>

+ 1 - 1
src/pages/Square/PopularProject.vue

@@ -10,7 +10,7 @@
     <div class="popular-list" v-else>
       <el-row class="popular-list-item" v-for="item in hotCrowdTestProjectVOs" :key="item.id">
         <el-col :span="19">
-          <img :src="require('../../assets/image/' + logo_background)" alt="logo-project" class="pull-left project-logo-img">
+          <img :src="logo_background" alt="logo-project" class="pull-left project-logo-img">
           <div style="margin-left: 55px; cursor: pointer;"  @click="goToProjectDetail(item.code)">
             <div class="list-item-title">
               {{item.name}}

+ 1 - 1
src/pages/Square/PopularTask.vue

@@ -9,7 +9,7 @@
     <div class="popular-list" v-else>
       <el-row class="popular-list-item" v-for="item in hotCrowdTaskVOs" :key="item.id">
         <el-col :span="19">
-          <img :src="require('../../assets/image/' + logo_transparent)" alt="logo-project" class="pull-left project-logo-img">
+          <img :src="logo_transparent" alt="logo-project" class="pull-left project-logo-img">
           <div style="margin-left: 55px; cursor: pointer;"  @click="goToTaskDetail(item.projectId,item.code)">
             <div class="list-item-title" >
               {{item.title}}

+ 2 - 2
src/pages/Square/Square2.0.vue

@@ -110,7 +110,6 @@
         this.$router.push('/home');
       },
       handleTabClick(tab){
-          console.log("handleTabClick ");
         this.currTab = tab.name
         this.activePage = 1;
         this.searchVal = '';
@@ -132,7 +131,8 @@
         this.searchType = tab.name;
         this.currTab = tab.name;
         this.activePage = 1;
-        this.$refs.searchInput.focus()
+        this.$refs.searchInput.focus();
+        this.searchData();
       },
 
       loadData(){

+ 2 - 1
src/pages/UserCenter/ModifyPsw.vue

@@ -30,6 +30,7 @@
   import Http from '@/js/http.js'
   import {logout, storageGet} from '@/js/index'
   import {notify} from '@/constants/index'
+  import {login_url} from '../../config/index'
 
   export default {
     name: "ModifyPsw",
@@ -77,7 +78,7 @@
                       // notify('success', '密码修改成功,请重新登录!')
                       window.alert('密码修改成功,请重新登录');
                       logout().then((res) => {
-                          window.location.href = process.env.LOGIN_URL;
+                          window.location.href = login_url;
                           // this.$router.push('/home')
                       })
 

+ 2 - 1
src/pages/UserCenter/ReBindingMail.vue

@@ -22,6 +22,7 @@
   import Http from '@/js/http.js'
   import {logout, storageGet} from '@/js/index'
   import {notify} from '@/constants/index'
+  import {login_url} from '../../config/index'
 
   export default {
     name: "ReBindingMail",
@@ -85,7 +86,7 @@
             // notify('success', '绑定成功');
             window.alert('邮箱修改成功, 请重新登录');
             logout().then((res) => {
-              window.location.href = process.env.LOGIN_URL;
+              window.location.href = login_url;
               // this.$router.push('/home')
             })
           }

+ 8 - 0
src/utils/filters.js

@@ -0,0 +1,8 @@
+export const configToJson = (config) => {
+  let configs = {};
+  Object.keys(config).forEach(function (key){
+    let confValue = JSON.parse(config[key]);
+    configs[Object.keys(confValue)[0]] = confValue[Object.keys(confValue)[0]];
+  })
+  return configs;
+}

+ 8 - 0
tool4deploy-privatecloud/conf.d/nginx.conf

@@ -22,6 +22,14 @@ server {
             proxy_pass http://crowd_backend:8080;
         }
 
+        location /page {
+            proxy_pass http://user.mooctest.net:8081;
+        }
+
+        location  ~ ^/(js|vendor|css|fonts|images)/.*$ {
+            proxy_pass http://user.mooctest.net:8081;
+        }
+
         #error_page  404              /404.html;
 
         # redirect server error pages to the static page /50x.html