Bläddra i källkod

Merge branch 'master' of git.xiaojukeji.com:jacklijiajia/thoth-frontend

qinzhipeng_v 5 år sedan
förälder
incheckning
16b9f9402d

+ 4 - 1
package.json

@@ -32,9 +32,12 @@
     "vue": "2.6.10",
     "vue-json-viewer": "^2.2.8",
     "vue-router": "3.0.6",
+    "vuedraggable": "^2.23.2",
     "vuex": "3.1.0",
     "wangeditor": "^3.1.1",
-    "xlsx": "^0.15.0"
+    "xlsx": "^0.15.0",
+    "qrcodejs2": "0.0.2",
+    "vue-qr": "^2.2.1"
   },
   "devDependencies": {
     "@babel/core": "7.0.0",

+ 43 - 0
src/api/KanBan.js

@@ -0,0 +1,43 @@
+import request from '@/utils/request'
+import { mockUrl } from '@/apiConfig/api'
+// ================================== Interface ======================================
+
+// const mockUrl = 'http://172.23.161.241:8980' // 线下
+// const mockUrl = 'http://10.179.24.123:8980' // 线上
+
+// 创建文件夹
+export function createComment(data) {
+  return request({
+    url: mockUrl + '/comment/create',
+    method: 'post',
+    data
+  })
+}
+
+// 更新文件夹
+export function updateComment(data) {
+  return request({
+    url: mockUrl + '/comment/update',
+    method: 'post',
+    data
+  })
+}
+
+// 删除文件
+export function deleteComment(id, data) {
+  return request({
+    url: mockUrl + `/comment/delete?id=` + id,
+    method: 'post',
+    data
+  })
+}
+
+// list
+export function listComment(data) {
+  return request({
+    url: mockUrl + '/comment/list',
+    method: 'post',
+    data
+  })
+}
+

+ 9 - 0
src/api/projectPage.js

@@ -127,3 +127,12 @@ export function teamMembers(data) {
     data
   })
 }
+
+// 看板
+export function listMap(data) {
+  return request({
+    url: mockUrl + '/task/listMap',
+    method: 'post',
+    data
+  })
+}

+ 47 - 3
src/views/Platform/defectManagement.vue

@@ -20,11 +20,11 @@
             <el-select v-model="queryCode.repairResult" size="medium" style="width:15%;margin-right: 10px;" clearable placeholder="修复状态">
               <el-option v-for="item in repairResultStr" :key="item.code" :label="item.name" :value="item.code" />
             </el-select>
-            <el-button type="primary" size="medium" style="margin-right:10px;" icon="el-icon-plus" circle @click="timeShow=! timeShow" />
+            <el-button type="primary" size="medium" style="margin-right:10px;" icon="el-icon-plus" circle @click="timeShow = !timeShow, isPlatformShow = !isPlatformShow, queryCode.platformType = '', isBusinessShow === true ? isBusinessShow = false : isBusinessShow = false" />
           </div>
           <div class="set-between">
-            <el-button type="primary" plain size="medium" @click="dataQuery(queryCode)">查询</el-button>
-            <el-button type="primary" plain size="medium" @click="createdCode()">新增</el-button>
+            <el-button type="primary" size="medium" plain @click="dataQuery(queryCode)">查询</el-button>
+            <el-button type="primary" size="medium" plain @click="createdCode()">新增</el-button>
           </div>
         </el-form>
         <el-date-picker
@@ -37,6 +37,12 @@
           end-placeholder="创建结束时间"
           clearable
         />
+        <el-select v-if="isPlatformShow" v-model="queryCode.platformType" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="平台类型" @change="clickChangeBusiness(queryCode.platformType)">
+          <el-option v-for="item in platformTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+        </el-select>
+        <el-select v-if="isBusinessShow" v-model="queryCode.clientType" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="业务模块" @change="clickChangeModule(queryCode.clientType)">
+          <el-option v-for="item in businessTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+        </el-select>
         <div class="set-locate">
           <el-table
             :data="tableData"
@@ -374,13 +380,17 @@
 
 <script>
 import { bugList, bugGet, bugDelete, bugUpdate, bugCreate, bugCopy, taskListCreate, bugGetEnum } from '@/api/defectManage'
+import { projectGetTypeMap } from '@/api/projectPage.js'
 
 export default {
   name: 'DefectManage',
   data() {
     return {
+      isPlatformShow: false,
+      isBusinessShow: false,
       bugTypeStr: [],
       bugStatusStr: [],
+      bizOptionsRR: [],
       bizOptions: [{ name: '万象', value: 101 }, { name: '企业级', value: 100 }, { name: '滴滴代驾', value: 261 }, { name: 'prado', value: 330 }, { name: 'carbo', value: 331 }, { name: '海马', value: 309 }],
       bugLevelStr: [{ name: 'p0', value: 0 }, { name: 'p1', value: 1 }, { name: 'p2', value: 2 }, { name: 'p3', value: 3 }],
       reasonStr: [],
@@ -442,6 +452,7 @@ export default {
   },
   created() {
     this.getList()
+    this.forkDown()
     this.bugListSelect()
   },
   mounted() {
@@ -507,6 +518,39 @@ export default {
         this.statistics = res.query
       })
     },
+    // 业务线数据获取
+    forkDown() {
+      projectGetTypeMap().then(res => {
+        if (res.code === 200) {
+          this.bizOptionsRR = res.data
+          if (this.bizJson) {
+            this.platformTypeStr = this.bizOptionsRR.filter(value => value.code === parseInt(this.bizJson))[0].child
+            this.$set(this.queryCode, 'platformType', '')
+            this.$set(this.queryCode, 'clientType', '')
+          } else {
+            this.isPlatformShow = false
+            this.isBusinessShow = false
+          }
+        } else {
+          this.errorFun('业务线数据获取失败')
+        }
+      })
+    },
+    // 业务线取子数据
+    clickChangeBusiness(e) {
+      if (e && this.platformTypeStr.filter(value => value.code === e)[0].child) {
+        this.isBusinessShow = true
+        this.businessTypeStr = this.platformTypeStr.filter(value => value.code === e)[0].child
+        this.$set(this.queryCode, 'clientType', '')
+      } else {
+        this.isBusinessShow = false
+      }
+    },
+    clickChangeModule(e) {
+      if (!e) {
+        this.isBusinessShow = false
+      }
+    },
     dataQueryInSearch(e) {
       this.bizJson = localStorage.getItem('key')
       this.indexPage = e

+ 488 - 56
src/views/onlineProblem/problemList.vue

@@ -1,61 +1,382 @@
 <template>
-  <div style="width: 100%;margin-left: 10px;">
-    <div style="margin: 2% 0;">
-      <el-form :model="queryCode">
-        <!-- <el-select v-model="queryCode.taskId" clearable placeholder="任务" style="width:10%;margin:0 5px;">
-          <el-option v-for="item in taskIdStr" :key="item.id" :label="item.name" :value="item.id" />
-        </el-select>
-        <el-select v-model="queryCode.status" clearable placeholder="bug状态" style="width:10%;margin-right:5px;">
-          <el-option v-for="item in bugStatusStr" :key="item.code" :label="item.name" :value="item.code" />
-        </el-select> -->
-        <el-input v-model="queryCode.currentHandler" clearable filterable placeholder="处理人" style="width:12%;margin-right:5px;" />
-        <el-input v-model="queryCode.creator" clearable filterable placeholder="创建人" style="width:12%;margin-right:5px;" />
-        <el-date-picker v-model="queryCode.gmtCreateBegin" style="width:19%;margin-right:5px;" type="datetime" placeholder="创建时间" />
-        <!-- <el-date-picker v-model="queryCode.gmtCreateEnd" style="width:12%;margin-right:5px;" type="datetime" placeholder="截止时间" /> -->
-        <el-input v-model="queryCode.bugName" clearable filterable placeholder="主题" style="width:12%;margin-right:5px;" />
-        <el-select v-model="queryCode.priority" clearable placeholder="故障级别" style="width:10%;margin-right:5px;">
-          <el-option v-for="item in bugStatusPriority" :key="item.code" :label="item.name" :value="item.code" />
-        </el-select>
-        <el-button type="primary" @click="dataQuery(queryCode)">查询</el-button>
-        <el-button type="primary" style="margin: 1% 5px;" @click="createdCode()">新建线上问题</el-button>
-      </el-form>
-    </div>
+  <div style="width: 100%;">
+    <div class="set-background">
+      <div class="block">
+        <el-form :model="queryCode">
+          <div class="set-between">
+            <!-- <el-form-item label="创建时间" label-width="70px"><el-date-picker v-model="queryCode.dateQuery" align="left" size="medium" type="datetime" style="width:76%;" placeholder="选择日期" /></el-form-item> -->
+            <el-input v-model="queryCode.currentHandler" placeholder="处理人" autocomplete="off" clearable size="medium" style="width:13%;margin-right: 15px;" />
+            <el-input v-model="queryCode.creator" placeholder="提交人" autocomplete="off" clearable size="medium" style="width:13%;margin-right: 15px;" />
+            <el-input v-model="queryCode.bugName" placeholder="主题" autocomplete="off" clearable size="medium" style="width:13%;margin-right: 15px;" />
+            <el-select v-model="queryCode.taskId" size="medium" style="width:15%;margin-right: 15px;" clearable placeholder="任务">
+              <el-option v-for="item in taskIdStr" :key="item.id" :label="item.name" :value="item.id" />
+            </el-select>
+            <el-select v-model="queryCode.status" size="medium" style="width:15%;margin-right: 15px;" clearable placeholder="bug状态">
+              <el-option v-for="item in bugStatusStr" :key="item.code" :label="item.name" :value="item.code" />
+            </el-select>
+            <el-select v-model="queryCode.priority" size="medium" style="width:15%;margin-right: 15px;" clearable placeholder="级别">
+              <el-option v-for="item in bugStatusPriority" :key="item.code" :label="item.name" :value="item.code" />
+            </el-select>
+            <el-select v-model="queryCode.repairResult" size="medium" style="width:15%;margin-right: 10px;" clearable placeholder="修复状态">
+              <el-option v-for="item in repairResultStr" :key="item.code" :label="item.name" :value="item.code" />
+            </el-select>
+            <el-button type="primary" size="medium" style="margin-right:10px;" icon="el-icon-plus" circle @click="timeShow=! timeShow" />
+          </div>
+          <div class="set-between">
+            <el-button type="primary" plain size="medium" @click="dataQuery(queryCode)">查询</el-button>
+            <el-button type="primary" plain size="medium" @click="createdCode()">新增</el-button>
+          </div>
+        </el-form>
+        <el-date-picker
+          v-show="timeShow"
+          v-model="timeInterval"
+          size="medium"
+          type="datetimerange"
+          range-separator="至"
+          start-placeholder="创建开始时间"
+          end-placeholder="创建结束时间"
+          clearable
+        />
+        <div class="set-locate">
+          <el-table
+            :data="tableData"
+            border
+            style="width: 100%"
+            size="mini"
+          >
+            <el-table-column
+              prop="id"
+              label="ID"
+              align="center"
+              width="60"
+            />
+            <el-table-column
+              label="主题"
+              align="center"
+              width="180"
+              show-overflow-tooltip
+            >
+              <template slot-scope="scope">
+                <a href="javascript:void(0)" style="color:#20a0ff" @click="toReportView(scope.row.id)">{{ scope.row.bugName }}</a>
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="priorityName"
+              label="级别"
+              align="center"
+              width="60"
+            />
+            <el-table-column
+              label="状态"
+              align="center"
+            >
+              <template slot-scope="scope">
+                <el-tag type="success" size="medium"><span>{{ scope.row.bugStatusName }}</span></el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="currentHandlerList"
+              label="处理人"
+              align="center"
+              show-overflow-tooltip
+            />
+            <el-table-column
+              prop="creatorList"
+              label="提交人"
+              align="center"
+              show-overflow-tooltip
+            />
+            <el-table-column
+              prop="assignerList"
+              label="责任人"
+              align="center"
+              show-overflow-tooltip
+            />
+            <el-table-column
+              prop="repairResultName"
+              label="修复结果"
+              align="center"
+              width="70"
+              show-overflow-tooltip
+            />
+            <el-table-column
+              prop="gmtCreate"
+              label="创建日期"
+              align="center"
+              show-overflow-tooltip
+            />
+            <el-table-column
+              label="操作"
+              align="center"
+              width="220"
+            >
+              <template v-slot="scope">
+                <div>
+                  <el-button size="mini" type="primary" plain @click="queryPresentation(scope.row)">更新</el-button>
+                  <el-button size="mini" type="danger" plain @click="delePresentation(scope.row.id)">删除</el-button>
+                  <el-button size="mini" type="info" plain @click="copyArrange(scope.row.id)">复制</el-button>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div class="set-locate">
+            <h4>缺陷分析数据</h4>
+            <el-table
+              :data="[statistics]"
+              border
+              style="width: 100%"
+              size="mini"
+            >
+              <el-table-column
+                prop="totalBug"
+                label="有效Bug总数"
+                align="center"
+              />
+              <el-table-column
+                prop="invalidBug"
+                label="无效Bug"
+                align="center"
+              />
+              <el-table-column
+                prop="fixBug"
+                label="已解决"
+                align="center"
+              />
+              <el-table-column
+                prop="rateOfFix"
+                label="修复率"
+                align="center"
+              />
+              <el-table-column
+                prop="remainBug"
+                label="遗留"
+                align="center"
+              />
+              <el-table-column
+                prop="rateOfReopen"
+                label="Reopen率"
+                align="center"
+              />
+              <el-table-column
+                prop="overnightRate"
+                label="过夜率"
+                align="center"
+              />
+              <el-table-column
+                prop="fixTime"
+                label="修复时长"
+                align="center"
+              />
+              <el-table-column
+                prop="p0"
+                label="P0"
+                align="center"
+              />
+              <el-table-column
+                prop="p1"
+                label="P1"
+                align="center"
+              />
+              <el-table-column
+                prop="other"
+                label="其他"
+                align="center"
+              />
+            </el-table>
+            <el-tooltip effect="dark" placement="bottom">
+              <div slot="content"><div>总数: 搜索结果下的所有有效缺陷不包含无效bug和重复bug</div> <div style="margin:5px 0">已解决: 状态为已完成并且修复结果为已修复或不修复的bug</div><div style="margin:5px 0">遗留bug: 状态不是已完成状态的bug</div><div style="margin:5px 0">reopen率: reopen次数/bug总数</div><div style="margin:5px 0">过夜: 创建时间-修复时间 >24h/bug总数</div><div style="margin:5px 0">修复时长: 创建时间-修复时间,不包含节假日</div><div style="margin:5px 0">其他: 除p0,p1级之外的bug</div><div>无效bug: 修复结果为无效 或者重复的bug</div></div>
+              <span class="titleDescription">统计规则说明<i class="el-icon-question" /> </span>
+            </el-tooltip>
+          </div>
+          <el-pagination style="margin-top:30px;" align="center" :current-page="curIndex" :page-sizes="[5, 10, 20]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+        </div>
+      </div>
+      <el-dialog class="adjustHeight" :title="titName" :visible.sync="dialogFormVisible" width="70%">
+        <el-form ref="form" :model="form" :rules="serviceDataRules">
+          <div class="set-background">
+            <el-form-item label="标题" :label-width="formLabelWidth"><el-input v-model="form.bugName" autocomplete="off" placeholder="普惠质量产品工具平台..." style="width:77.2%;" /></el-form-item>
+            <div style="display:flex;">
+              <el-form-item style="flex-grow:1" prop="bizId" label="业务线" :label-width="formLabelWidth1">
+                <el-select v-model="form.bizId" placeholder="业务线" style="width:54.5%;">
+                  <el-option v-for="item in bizOptions" :key="item.value" :label="item.name" :value="item.value" />
+                </el-select>
+              </el-form-item>
+              <el-form-item style="flex-grow:1" label="业务模块" prop="businessType" :label-width="formLabelWidth1">
+                <el-select v-model="form.businessType" placeholder="业务模块" style="width:54.5%;">
+                  <el-option v-for="item in businessTypeStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+            </div>
+            <div style="display:flex;">
+              <el-form-item style="flex-grow:1" prop="taskId" label="任务" :label-width="formLabelWidth1">
+                <el-select v-model="form.taskId" placeholder="任务" style="width:54.5%;">
+                  <el-option v-for="item in taskIdStr" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+              </el-form-item>
+              <el-form-item style="flex-grow:1" label="平台类型" prop="platformType" :label-width="formLabelWidth1">
+                <el-select v-model="form.platformType" placeholder="平台类型" style="width:54.5%;" @change="clickChangeType(form.platformType)">
+                  <el-option v-for="item in platformTypeStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+            </div>
+            <div style="display:flex;">
+              <el-form-item style="flex-grow:1" label="类型" prop="bugType" :label-width="formLabelWidth1">
+                <el-select v-model="form.bugType" style="width:54.5%;" placeholder="类型">
+                  <el-option v-for="item in bugTypeStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+              <el-form-item style="flex-grow:1" label="发现方式" prop="discoveryMethod" :label-width="formLabelWidth1">
+                <el-select v-model="form.discoveryMethod" style="width:54.5%;" placeholder="发现方式">
+                  <el-option v-for="item in discoveryMethodStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+            </div>
+            <div style="display:flex;">
+              <el-form-item style="flex-grow:1" label="级别" prop="priority" :label-width="formLabelWidth1">
+                <el-select v-model="form.priority" style="width:54.5%;" placeholder="级别">
+                  <el-option v-for="item in bugLevelStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+              <el-form-item style="flex-grow:1" label="问题原因" prop="reason" :label-width="formLabelWidth1">
+                <el-select v-model="form.reason" style="width:54.5%;" placeholder="问题原因">
+                  <el-option v-for="item in reasonStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+            </div>
+            <div style="display:flex;">
+              <el-form-item style="flex-grow:1" label="状态" prop="status" :label-width="formLabelWidth1">
+                <el-select v-model="form.status" placeholder="状态" style="width:54.5%;" @change="buildShow(form.status)">
+                  <el-option v-for="item in bugStatusStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+              <el-form-item style="flex-grow:1" label="所处阶段" prop="stage" :label-width="formLabelWidth1">
+                <el-select v-model="form.stage" placeholder="所处阶段" style="width:54.5%;">
+                  <el-option v-for="item in stageStr" :key="item.name" :label="item.name" :value="item.name" />
+                </el-select>
+              </el-form-item>
+            </div>
+            <el-form-item label="bug描述" prop="bugDescribe" :label-width="formLabelWidth"><el-input v-model="form.bugDescribe" type="textarea" placeholder="bug描述" rows="2" style="width:77.2%;" /></el-form-item>
+          </div>
+          <div style="display:flex;">
+            <el-form-item label="创建人" :label-width="formLabelWidth"><el-input v-model="form.creator" autocomplete="off" style="width:67%;" /></el-form-item>
+            <el-form-item label="bug责任人" prop="assigner" :label-width="formLabelWidth"><el-input v-model="form.assigner" autocomplete="off" style="width:67%;" /></el-form-item>
+          </div>
+          <div style="flex:1">
+            <el-form-item v-show="statusShow" label="问题原因和修复方法" :label-width="formLabelWidth"><el-input v-model="form.reasonsAndSolutionForTheProblem" type="textarea" placeholder="问题原因和修复方法" rows="4" style="width:77.2%;" /></el-form-item>
+          </div>
+          <div style="flex:1">
+            <el-form-item label="bug处理人" prop="currentHandler" :label-width="formLabelWidth"><el-input v-model="form.currentHandler" autocomplete="off" style="width:67%;" /></el-form-item>
+            <el-form-item label="app版本号" :label-width="formLabelWidth"><el-input v-model="form.appVersion" autocomplete="off" style="width:67%;" /></el-form-item>
+            <el-form-item label="地图类型" :label-width="formLabelWidth"><el-input v-model="form.mapType" autocomplete="off" style="width:67%;" /></el-form-item>
+            <el-form-item label="地图版本号" :label-width="formLabelWidth"><el-input v-model="form.mapVersion" autocomplete="off" style="width:67%;" /></el-form-item>
+            <el-form-item label="SDK版本" :label-width="formLabelWidth"><el-input v-model="form.sdkVersion" autocomplete="off" style="width:67%;" /></el-form-item>
+            <el-form-item v-show="repairShow" label="修复结果" :label-width="formLabelWidth">
+              <el-select v-model="form.repairResult" placeholder="发现方法">
+                <el-option v-for="item in repairResultStr" :key="item.name" :label="item.name" :value="item.name" />
+              </el-select>
+            </el-form-item>
+          </div>
+          <el-form-item label="附件" :label-width="formLabelWidth">
+            <el-upload
+              class="upload-demo"
+              multiple
+              capture
+              accept="image/jpeg, image/png, image/gif, audio/mp4, video/mp4, audio/mpeg, application/vnd.ms-excel"
+              :on-change="handleChange"
+              :file-list="fileList"
+              action="http://page-daily.kuaidadi.com/upload/img.node"
+            >
+              <!-- action="http://page-daily.kuaidadi.com/upload/img.node" 线下 -->
+              <!-- action="http://star.xiaojukeji.com/upload/img.node" 线上 -->
+              <!-- action="https://jsonplaceholder.typicode.com/posts/" 原始地址-->
+              <el-button size="small" type="primary">点击上传</el-button>
+            </el-upload>
+          </el-form-item>
+          {{ form.accessory }}
+
+          <!-- <el-form-item label="逻辑删" :label-width="formLabelWidth">
+            <el-select v-model="form.isDelete" placeholder="发现方法">
+              <el-option v-for="item in isDeleteStr" :key="item.value" :label="item.name" :value="item.value" />
+            </el-select>
+          </el-form-item> -->
+          <!-- <el-form-item label="reopen的次数" :label-width="formLabelWidth"> <el-input v-model="form.reopenTimes" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="业务线" prop="bizId" :label-width="formLabelWidth"><el-input v-model="form.bizId" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="模块" :label-width="formLabelWidth"><el-input v-model="form.moduleId" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="项目名" :label-width="formLabelWidth"><el-input v-model="form.projectName" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="项目ID" :label-width="formLabelWidth"><el-input v-model="form.projectId" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="测试计划ID" prop="planId" :label-width="formLabelWidth"><el-input v-model="form.planId" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="caseID" :label-width="formLabelWidth"><el-input v-model="form.caseId" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="bug创建人" :label-width="formLabelWidth"> <el-input v-model="form.creator" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="开始开发时间" :label-width="formLabelWidth"><el-input v-model="form.startDevTime" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="开始等待测试时间" :label-width="formLabelWidth"><el-input v-model="form.waitTestTime" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="创建时间" :label-width="formLabelWidth"><el-input v-model="form.gmtCreate" autocomplete="off" /></el-form-item> -->
+          <!-- <el-form-item label="修改时间" :label-width="formLabelWidth"><el-input v-model="form.gmtModify" autocomplete="off" /></el-form-item> -->
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button @click="dialogFormVisible = false">取 消</el-button>
+          <el-button type="primary" @click="titName === '新建' ? createFormData(form) : queryFormData(form)">确 定</el-button>
+        </div>
+      </el-dialog>
 
-    <el-table :data="tableData" fit>
-      <el-table-column label="ID" min-width="120" align="center">
-        <template slot-scope="scope">{{ scope.row.id }}</template>
-      </el-table-column>
-      <el-table-column label="主题" min-width="230" align="center">
-        <template slot-scope="scope"><a href="javascript:void(0)" style="color:#20a0ff" @click="toReportView(scope.row.id)">{{ scope.row.bugName }}</a></template>
-      </el-table-column>
-      <el-table-column label="处理人" min-width="150" align="center">
-        <template slot-scope="scope">{{ scope.row.currentHandlerList }}</template>
-      </el-table-column>
-      <el-table-column label="创建日期" min-width="250" align="center">
-        <template slot-scope="scope">{{ scope.row.gmtCreate }}</template>
-      </el-table-column>
-      <el-table-column label="级别" width="150" align="center">
-        <template slot-scope="scope"><span>{{ scope.row.priorityName }}</span></template>
-      </el-table-column>
-      <el-table-column label="状态" width="150" align="center">
-        <template slot-scope="scope"><span>{{ scope.row.bugStatusName }}</span></template>
-      </el-table-column>
-      <el-table-column fixed="right" label="操作" width="225" align="center">
-        <template slot-scope="scope">
-          <el-button size="mini" type="primary" @click="queryPresentation(scope.row)">更新</el-button>
-          <el-button size="mini" type="primary" @click="delePresentation(scope.row.id)">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <el-pagination style="margin-top:30px;" align="center" :current-page="curIndex" :page-sizes="[5, 10, 20]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
-  </div>
-</template>
+      <el-dialog :visible.sync="dialogFormQuery" width="70%">
+        <el-form :model="form" size="mini">
+          <el-form-item :label-width="formLabelWidth" style="margin-bottom:-10px;"><span style="font-weight:bold;font-size:20px;margin-left:-60px;">主题 : </span>{{ form.bugName }}</el-form-item><hr>
+          <div style="display:flex;">
+            <div style="flex:1">
+              <el-form-item label="任务 : " class="styline" :label-width="formLabelWidth1">{{ form.projectName }}</el-form-item>
+              <el-form-item label="级别 : " :label-width="formLabelWidth1">{{ form.priority }}</el-form-item>
+              <el-form-item label="reopen的次数 : " :label-width="formLabelWidth1">{{ form.reopenTimes }}</el-form-item>
+              <el-form-item label="bug状态 : " :label-width="formLabelWidth1">{{ form.status }}</el-form-item>
+              <el-form-item label="bug类型 : " :label-width="formLabelWidth1">{{ form.bugType }}</el-form-item>
+              <el-form-item label="bug描述 : " :label-width="formLabelWidth1">{{ form.bugDescribe }}</el-form-item>
+              <el-form-item v-show="statusShow" label="问题原因和修复方法" :label-width="formLabelWidth">{{ form.reasonsAndSolutionForTheProblem }}</el-form-item>
+              <el-form-item label="问题原因 : " :label-width="formLabelWidth1">{{ form.reason }}</el-form-item>
+              <el-form-item label="平台类型 : " :label-width="formLabelWidth1">{{ form.platformType }}</el-form-item>
+              <el-form-item label="业务模块 : " :label-width="formLabelWidth1">{{ form.businessType }}</el-form-item>
+              <el-form-item label="所处阶段 : " :label-width="formLabelWidth1">{{ form.stage }}</el-form-item>
+              <el-form-item label="发现方法 : " :label-width="formLabelWidth1">{{ form.discoveryMethod }}</el-form-item>
+              <el-form-item v-show="repairShow" label="修复结果 : " :label-width="formLabelWidth1">{{ form.repairResult }}</el-form-item>
+              <el-form-item label="os类型 : " :label-width="formLabelWidth1">{{ form.osType }}</el-form-item>
+              <el-form-item label="机型 : " :label-width="formLabelWidth1">{{ form.model }}</el-form-item>
+              <el-form-item label="网络类型 : " :label-width="formLabelWidth1">{{ form.networkType }}</el-form-item>
+              <el-form-item label="SDK版本 : " :label-width="formLabelWidth1">{{ form.sdkVersion }}</el-form-item>
+              <el-form-item label="app版本号 : " :label-width="formLabelWidth1">{{ form.appVersion }}</el-form-item>
+              <el-form-item label="地图类型 : " :label-width="formLabelWidth1">{{ form.mapType }}</el-form-item>
+              <el-form-item label="地图版本号 : " :label-width="formLabelWidth1">{{ form.mapVersion }}</el-form-item>
+              <el-form-item label="附件 : " :label-width="formLabelWidth1">{{ form.accessory }}</el-form-item>
+            </div>
+            <div style="flex:1; margin-left:30px;">
+              <el-form-item label="业务线 : " :label-width="formLabelWidth1">{{ form.bizId }}</el-form-item>
+              <el-form-item label="bug责任人 : " :label-width="formLabelWidth1">{{ form.assigner }}</el-form-item>
+              <el-form-item label="bug创建人 : " :label-width="formLabelWidth1">{{ form.creator }}</el-form-item>
+              <el-form-item label="bug处理人 : " :label-width="formLabelWidth1">{{ form.currentHandler }}</el-form-item>
+              <el-form-item label="开始开发时间 : " :label-width="formLabelWidth1">{{ form.startDevTime }}</el-form-item>
+              <el-form-item label="开始等待测试时间 : " :label-width="formLabelWidth1">{{ form.waitTestTime }}</el-form-item>
+              <el-form-item label="创建时间 : " :label-width="formLabelWidth1">{{ form.gmtCreate }}</el-form-item>
+            </div>
+          </div>
+          <!-- <el-form-item label="caseID" :label-width="formLabelWidth">{{ form.caseId }}</el-form-item> -->
+          <!-- <el-form-item label="项目名" :label-width="formLabelWidth">{{ form.projectName }}</el-form-item> -->
+          <!-- <el-form-item label="项目ID" :label-width="formLabelWidth">{{ form.projectId }}</el-form-item> -->
+          <!-- <el-form-item label="测试计划ID" :label-width="formLabelWidth">{{ form.planId }}</el-form-item> -->
+          <!-- <el-form-item label="逻辑删" :label-width="formLabelWidth">{{ form.isDelete }}</el-form-item> -->
+          <!-- <el-form-item label="业务线" :label-width="formLabelWidth">{{ form.bizId }}</el-form-item> -->
+          <!-- <el-form-item label="模块ID" :label-width="formLabelWidth">{{ form.moduleId }}</el-form-item> -->
+          <!-- <el-form-item label="修改时间" :label-width="formLabelWidth">{{ form.gmtModify }}</el-form-item> -->
+
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button type="primary" @click="dialogFormQuery = false">关 闭</el-button>
+        </div>
+      </el-dialog>
+    </div>
+  </div></template>
 
 <script>
-import { bugList, bugGet, bugDelete, taskListCreate, bugGetEnum } from '@/api/defectManage'
+import { bugList, bugGet, bugDelete, bugUpdate, bugCreate, bugCopy, taskListCreate, bugGetEnum } from '@/api/defectManage'
 
 export default {
-  name: 'DefectManagement',
+  name: 'DefectManage',
   data() {
     return {
       bugTypeStr: [],
@@ -69,6 +390,7 @@ export default {
       businessTypeStr: [],
       bugStatusPriority: [],
       repairResultStr: [],
+      statistics: [],
       isDeleteStr: [{ name: '保留', value: 0 }, { name: '删除', value: 1 }],
       serviceDataRules: {
         bizId: [{ required: true, message: '业务线不能为空', trigger: 'change' }],
@@ -91,13 +413,22 @@ export default {
       userNames: localStorage.getItem('realname'),
       bizJson: localStorage.getItem('key'),
       pageSize: 20,
-      curIndex: 0,
+      curIndex: 1,
       total: 0,
       show2: '',
+      form: {
+        id: ''
+      },
       tableData: [],
-      queryCode: {},
+      queryCode: {
+        stage: 6,
+        online: true
+      },
       statusShow: false,
       repairShow: false,
+      timeShow: false,
+      dialogFormVisible: false,
+      dialogFormQuery: false,
       formLabelWidth: '11%',
       formLabelWidth1: '22%',
       serviceTypeEnumList: [],
@@ -105,7 +436,9 @@ export default {
       bizIdEnumList: [],
       objData: '',
       userData: '',
+      titName: '',
       taskIdStr: '',
+      timeInterval: [],
       fileList: [],
       fileDbList: []
     }
@@ -115,17 +448,21 @@ export default {
     this.bugListSelect()
   },
   mounted() {
+    document.getElementsByClassName('app-main')[0].style.cssText = 'overflow:auto'
     this.getQueryData()
   },
   methods: {
     getList() {
       this.bizJson = localStorage.getItem('key')
       this.indexPage = {
+        online: true,
+        stage: 6,
         bizId: this.bizJson,
         pageSize: this.pageSize,
         curIndex: this.curIndex
       }
       bugList(this.indexPage).then(res => {
+        this.statistics = res.query
         this.tableData = res.data
         this.total = res.total
       })
@@ -158,13 +495,21 @@ export default {
     dataQuery(e) {
       this.bizJson = localStorage.getItem('key')
       this.indexPage = e
-      this.curIndex = 0
+      this.curIndex = 1
       this.indexPage.bizId = this.bizJson
       this.indexPage.pageSize = this.pageSize
       this.indexPage.curIndex = this.curIndex
+      if (this.timeShow) {
+        this.indexPage.gmtCreateBegin = this.timeInterval[0]
+        this.indexPage.gmtCreateEnd = this.timeInterval[1]
+      } else {
+        this.indexPage.gmtCreateBegin = ''
+        this.indexPage.gmtCreateEnd = ''
+      }
       bugList(this.indexPage).then(res => {
         this.tableData = res.data
         this.total = res.total
+        this.statistics = res.query
       })
     },
     dataQueryInSearch(e) {
@@ -173,6 +518,13 @@ export default {
       this.indexPage.bizId = this.bizJson
       this.indexPage.pageSize = this.pageSize
       this.indexPage.curIndex = this.curIndex
+      if (this.timeShow) {
+        this.indexPage.gmtCreateBegin = this.timeInterval[0]
+        this.indexPage.gmtCreateEnd = this.timeInterval[1]
+      } else {
+        this.indexPage.gmtCreateBegin = ''
+        this.indexPage.gmtCreateEnd = ''
+      }
       bugList(this.indexPage).then(res => {
         this.tableData = res.data
         this.total = res.total
@@ -196,7 +548,15 @@ export default {
           this.$message({ type: 'success', message: '已取消' })
         })
     },
+    copyArrange(e) {
+      this.userData = { id: e, ename: this.userInformation, name: this.userNames }
+      bugCopy(this.userData, e).then(res => {
+        this.getList()
+        this.successFun()
+      })
+    },
     queryPresentation(ele) {
+      this.titName = '编辑'
       this.form = ele
       for (var a of this.bizOptions) {
         if (ele.bizId === a.value) {
@@ -205,9 +565,27 @@ export default {
       }
       // this.bizId = ele.bizId
       this.form.taskId = ele.taskId
+      this.buildShow(ele)
       this.$router.push({ name: '更新线上问题', params: { formData: this.form }, query: { id: this.form.id }})
       // this.dialogFormVisible = true
     },
+    buildShow(ele) {
+      if (ele.status === '待回归' || ele === 2) {
+        this.statusShow = true
+      }
+      if (ele.repairResult === '已修复' || ele === 3) {
+        this.repairShow = true
+      }
+    },
+    queryFormData(form) {
+      this.userData = { id: '', ename: this.userInformation, name: this.userNames }
+      this.objData = { bugBaseInfo: this.form, user: this.userData }
+      bugUpdate(this.objData).then(res => {
+        res.code === 200 ? this.successFun() : this.errorFun()
+        this.dialogFormVisible = false
+        this.getList()
+      })
+    },
     getQueryData() {
       this.$route.query.code === 4 ? this.queryCode.taskId = this.$route.query.id : ''
       this.bizJson = localStorage.getItem('key')
@@ -216,6 +594,7 @@ export default {
       })
     },
     handleSizeChange(size) {
+      this.curIndex = 1
       this.pageSize = size
       this.dataQueryInSearch(this.queryCode)
     },
@@ -224,6 +603,8 @@ export default {
       this.dataQueryInSearch(this.queryCode)
     },
     createdCode() {
+      // this.titName = '新建'
+      // this.dialogFormVisible = true
       this.form = {}
       // this.$route.query.code === 4 ? this.form.taskId = this.$route.query.id : ''
       // if (this.$refs['form'] !== undefined) {
@@ -231,7 +612,22 @@ export default {
       // }
       this.$router.push({ name: '新建线上问题' })
     },
+    createFormData(form) {
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          // form.bizId = this.bizJson
+          this.userData = { id: '', ename: this.userInformation, name: this.userNames }
+          this.objData = { bugBaseInfo: form, user: this.userData }
+          bugCreate(this.objData).then(res => {
+            this.dialogFormVisible = false
+            this.getList()
+            res.code === 200 ? this.successFun() : this.errorFun()
+          })
+        }
+      })
+    },
     toReportView(e) {
+      // this.dialogFormQuery = true
       // this.buildShow(e)
       bugGet(e).then(res => {
         this.form = res.data
@@ -265,5 +661,41 @@ export default {
 </script>
 
 <style lang="stylus" scoped>
-
+  .set-background
+    background-color #F2F3F6
+    display flex
+    justify-content center
+    min-width 900px
+    .block
+      background-color rgba(255,255,255,1)
+      box-shadow 0px 0px 11px 0px rgba(238,240,245,1)
+      border-radius 7px
+      width 96%
+      margin 20px 0
+      padding 20px
+      min-height calc(100vh - 100px)
+    .block >>> .el-form
+      display flex
+      justify-content space-between
+      margin 10px 0px 15px 0px
+    .block >>> .el-form-item__content
+      margin-left 0 !important
+    .block >>> th
+      background-color #F0F2F4 !important
+    .block >>> .el-range-separator
+      padding 0
+    .set-between
+      display flex
+    .set-between >>> .el-button
+      height 36px
+    .set-between >>> .el-form-item
+      display flex
+      margin-right -35px
+    .set-locate
+      margin-top 25px
+      .titleDescription
+        font-size 12px
+        color rgba(244,121,121,1)
+        margin 30px 0px
+        display inline-block
 </style>

+ 68 - 12
src/views/projectManage/projectList/projectListIndex.vue

@@ -5,19 +5,23 @@
         <el-form :model="queryCode">
           <div class="set-between">
             <!-- <el-form-item label="创建时间" label-width="70px"><el-date-picker v-model="queryCode.dateQuery" align="left" size="medium" type="datetime" style="width:76%;" placeholder="选择日期" /></el-form-item> -->
-            <el-form-item label="项目名称" label-width="70px"><el-input v-model="queryCode.name" placeholder="请选择项目" autocomplete="off" clearable size="medium" style="width:76%;" /></el-form-item>
-            <el-form-item label="状态" label-width="40px">
-              <el-select v-model="queryCode.statusString" size="medium" style="width:60%;" clearable placeholder="状态">
-                <el-option v-for="item in statusOptionss" :key="item.code" :label="item.name" :value="item.code" />
-              </el-select>
-            </el-form-item>
+            <el-input v-model="queryCode.name" placeholder="请选择项目" autocomplete="off" clearable size="medium" style="width:17.5%;margin-right: 15px;" />
+            <el-select v-model="queryCode.statusString" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="状态">
+              <el-option v-for="item in statusOptionss" :key="item.code" :label="item.name" :value="item.code" />
+            </el-select>
+            <el-select v-show="isPlatformShow" v-model="queryCode.type" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="平台类型" @change="clickChangeBusiness(queryCode.type)">
+              <el-option v-for="item in platformTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+            </el-select>
+            <el-select v-show="isBusinessShow" v-model="queryCode.clientType" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="业务模块" @change="clickChangeModule(queryCode.clientType)">
+              <el-option v-for="item in businessTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+            </el-select>
           </div>
           <div class="set-between">
-            <el-button type="primary" plain size="medium" @click="dataQuery(queryCode)">查询</el-button>
-            <el-button type="primary" plain size="medium" @click="createdCode()">新增</el-button>
+            <el-button type="primary" size="medium" plain @click="dataQuery(queryCode)">查询</el-button>
+            <el-button type="primary" size="medium" plain @click="createdCode()">新增</el-button>
           </div>
         </el-form>
-        <div class="set-locate">
+        <div style="margin-top:22px">
           <el-table
             :data="list"
             border
@@ -83,7 +87,7 @@
               </template>
             </el-table-column>
           </el-table>
-          <el-pagination background style="margin-top:30px;" align="center" :current-page="curIndex" :page-size="pageSize" layout="prev, pager, next" :total="total" @current-change="handleCurrentChange" />
+          <el-pagination background style="margin-top:30px;" align="center" :current-page="curIndex" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" />
         </div>
       </div>
     </div>
@@ -91,11 +95,15 @@
 </template>
 
 <script>
-import { projectInit, deleteProject } from '@/api/projectPage.js'
+import { projectInit, deleteProject, projectGetTypeMap } from '@/api/projectPage.js'
 
 export default {
   data() {
     return {
+      isPlatformShow: false,
+      isBusinessShow: false,
+      platformTypeStr: [],
+      businessTypeStr: [],
       list: [],
       form: {},
       queryCode: {
@@ -103,7 +111,7 @@ export default {
       },
       queryListData: {},
       curIndex: 1,
-      pageSize: 20,
+      pageSize: 10,
       total: 0,
       pauseJumpData: {},
       dialogVisible: false,
@@ -116,6 +124,7 @@ export default {
   },
   created() {
     this.getList()
+    this.forkDown()
   },
   mounted() {
     document.getElementsByClassName('app-main')[0].style.cssText = 'overflow:auto'
@@ -160,10 +169,46 @@ export default {
       queryCode.bizId = localStorage.getItem('key')
       queryCode.pageSize = this.pageSize
       queryCode.curIndex = this.curIndex
+      this.emptyJudge(queryCode)
       projectInit(queryCode).then(res => {
         res.code === 200 ? this.list = res.data : this.errorFun(res.msg)
+        this.total = res.total
       })
     },
+    // 业务线数据获取
+    forkDown() {
+      projectGetTypeMap().then(res => {
+        if (res.code === 200) {
+          this.bizOptions = res.data
+          if (this.bizJson) {
+            this.isPlatformShow = true
+            this.platformTypeStr = this.bizOptions.filter(value => value.code === parseInt(this.bizJson))[0].child
+            this.$set(this.form, 'type', '')
+            this.$set(this.form, 'clientType', '')
+          } else {
+            this.isPlatformShow = false
+            this.isBusinessShow = false
+          }
+        } else {
+          this.errorFun('业务线数据获取失败')
+        }
+      })
+    },
+    // 业务线取子数据
+    clickChangeBusiness(e) {
+      if (e && this.platformTypeStr.filter(value => value.code === e)[0].child) {
+        this.isBusinessShow = true
+        this.businessTypeStr = this.platformTypeStr.filter(value => value.code === e)[0].child
+        this.$set(this.form, 'clientType', '')
+      } else {
+        this.isBusinessShow = false
+      }
+    },
+    clickChangeModule(e) {
+      if (!e) {
+        this.isBusinessShow = false
+      }
+    },
     dataQueryInSearch(queryCode) {
       this.Arra = []
       queryCode.statusString !== '' ? this.Arra.push(queryCode.statusString) : ''
@@ -171,6 +216,7 @@ export default {
       queryCode.bizId = localStorage.getItem('key')
       queryCode.pageSize = this.pageSize
       queryCode.curIndex = this.curIndex
+      this.emptyJudge(queryCode)
       projectInit(queryCode).then(res => {
         res.code === 200 ? this.list = res.data : this.errorFun(res.msg)
       })
@@ -187,6 +233,14 @@ export default {
         this.$router.push({ path: '/Platform/presentation/Acceptance', query: { projectId: scope }}) // 服务端
       }
     },
+    // 接口不接受空值处理
+    emptyJudge(obj) {
+      for (const key in obj) {
+        if (obj[key] === '') {
+          delete obj[key]
+        }
+      }
+    },
     // 任务创建
     changeaddTaskData(scope) {
       this.$router.push({ name: '任务创建', query: { id: scope.id }})
@@ -239,6 +293,8 @@ export default {
       background-color #F0F2F4 !important
     .set-between
       display flex
+    .set-between:first-child
+      width 80%
     .set-between >>> .el-button
       height 36px
     .set-between >>> .el-form-item

+ 4 - 4
src/views/projectManage/projectList/projectPreview.vue

@@ -15,10 +15,10 @@
           <el-select v-model="form.stage" size="medium" style="width:11%;margin-right: 15px;" clearable placeholder="进展" @change="updateData()">
             <el-option v-for="item in stageEnumList" :key="item.code" :label="item.name" :value="item.code" />
           </el-select>
-          <el-button type="primary" plain size="medium" @click="createDailyReport(form)">新建日报报告</el-button>
-          <el-button type="primary" plain size="medium" @click="createReport(form)">新建准出报告</el-button>
-          <el-button type="primary" plain size="medium" @click="changeaddTaskData()">新建任务</el-button>
-          <el-button type="primary" plain size="medium" @click="projectShowData()">编辑</el-button>
+          <el-button type="primary" size="medium" plain @click="createDailyReport(form)">新建日报报告</el-button>
+          <el-button type="primary" size="medium" plain @click="createReport(form)">新建准出报告</el-button>
+          <el-button type="primary" size="medium" plain @click="changeaddTaskData()">新建任务</el-button>
+          <el-button type="primary" size="medium" plain @click="projectShowData()">编辑</el-button>
         </div>
         <div class="display-messege">
           <span style="font-weight:bold;">项目名称 :</span>&nbsp;&nbsp;&nbsp;{{ form.name }}

+ 925 - 78
src/views/projectManage/taskList/taskListIndex.vue

@@ -1,25 +1,29 @@
 <template>
-  <div style="width: 100%;">
+  <div v-loading="loadingOnlineProcess" style="width: 100%;" element-loading-background="rgba(0, 0, 0, 0.7)" element-loading-text="拼命加载中">
     <div class="set-background">
       <div class="block">
-        <el-tabs v-model="activeName">
+        <el-tabs v-model="activeName" @tab-click="handleClick">
           <el-tab-pane label="列表" name="first">
             <el-form :model="form">
               <div class="set-between">
                 <!-- <el-form-item label="创建时间" label-width="70px"><el-date-picker v-model="form.createTime" align="left" size="medium" type="datetime" style="width:76%;" placeholder="选择日期" /></el-form-item> -->
-                <el-form-item label="任务名称" label-width="70px"><el-input v-model="form.name" placeholder="填写任务名称" autocomplete="off" clearable size="medium" style="width:76%;" /></el-form-item>
-                <el-form-item label="状态" label-width="40px">
-                  <el-select v-model="form.status" size="medium" style="width:60%;" clearable placeholder="状态">
-                    <el-option v-for="item in processStatusEnumList" :key="item.code" :label="item.name" :value="item.code" />
-                  </el-select>
-                </el-form-item>
+                <el-input v-model="form.name" placeholder="任务名称" autocomplete="off" clearable size="medium" style="width:17.5%;margin-right: 15px;" />
+                <el-select v-model="form.status" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="状态">
+                  <el-option v-for="item in processStatusEnumList" :key="item.code" :label="item.name" :value="item.code" />
+                </el-select>
+                <el-select v-show="isPlatformShow" v-model="form.type" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="平台类型" @change="clickChangeBusiness(form.type)">
+                  <el-option v-for="item in platformTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+                </el-select>
+                <el-select v-show="isBusinessShow" v-model="form.clientType" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="业务模块" @change="clickChangeModule(form.clientType)">
+                  <el-option v-for="item in businessTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+                </el-select>
               </div>
               <div class="set-between">
                 <el-button type="primary" plain size="medium" @click="dataQuery(form)">查询</el-button>
                 <el-button type="primary" plain size="medium" @click="createdCode()">新增</el-button>
               </div>
             </el-form>
-            <div class="set-locate">
+            <div style="margin-top:22px">
               <el-table
                 :data="tableData"
                 border
@@ -86,14 +90,172 @@
                   </template>
                 </el-table-column>
               </el-table>
-              <el-pagination background style="margin-top:30px;" align="center" :current-page="curIndex" :page-size="pageSize" layout="prev, pager, next" :total="total" @current-change="handleCurrentChange" />
+              <el-pagination background style="margin-top:30px;" align="center" :current-page="curIndex" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" />
             </div>
           </el-tab-pane>
           <el-tab-pane label="看板" name="second">
-            敬请期待
+            <el-form :model="formKanBan">
+              <div class="set-between-kanban">
+                <!-- <el-form-item label="创建时间" label-width="70px"><el-date-picker v-model="form.createTime" align="left" size="medium" type="datetime" style="width:76%;" placeholder="选择日期" /></el-form-item> -->
+                <el-select v-model="formKanBan.status" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="状态">
+                  <el-option v-for="item in processStatusEnumListKanBan" :key="item.code" :label="item.name" :value="item.code" />
+                </el-select>
+                <el-input v-model="formKanBan.tag" placeholder="填写标签名称" autocomplete="off" clearable size="medium" style="width:17.5%;margin-right: 15px;" />
+                <el-select v-show="isPlatformShow" v-model="formKanBan.type" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="平台类型" @change="clickChangeBusiness(formKanBan.type)">
+                  <el-option v-for="item in platformTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+                </el-select>
+                <el-select v-show="isBusinessShow" v-model="formKanBan.clientType" size="medium" style="width:17.5%;margin-right: 15px;" clearable placeholder="业务模块" @change="clickChangeModule(formKanBan.clientType)">
+                  <el-option v-for="item in businessTypeStr" :key="item.code" :label="item.name" :value="item.code" />
+                </el-select>
+                <el-button type="primary" size="medium" style="z-index:999" plain @click="kanBanQuery(formKanBan)">查询</el-button>
+              </div>
+            </el-form>
           </el-tab-pane>
         </el-tabs>
       </div>
+      <div v-show="activeName === 'second'" class="navigation-content">
+        <div v-show="isCollapsing" class="navigation">
+          <div class="collapse">
+            <span @click="isCollapsing = !isCollapsing">&lt;&lt; 收起</span>
+          </div>
+          <div class="scroll-navigate">
+            <div v-show="!isEmpty" class="empty-add">
+              <i class="el-icon-circle-plus" @click="addNewNode()" /><span @click="addNewNode()">新建文件夹</span>
+            </div>
+            <el-tree
+              v-show="isEmpty"
+              ref="treeBox"
+              icon-class="el-icon-caret-right"
+              :data="dealWithBusinessDate"
+              node-key="id"
+              highlight-current
+              :default-expanded-keys="defaultExpanded"
+              :props="defaultProps"
+              :expand-on-click-node="false"
+              style="margin-top:10px;min-width:100%;display:inline-block !important;"
+              @node-click="handleNodeClick"
+            >
+              <span slot-scope="{ node, data }" class="custom-tree-node" @mouseenter="mouseenter(data)" @mouseleave="mouseleave(data)">
+                <span v-if="data.spanAbsolute" @dblclick="dblclick(data)">{{ node.label }}</span>
+                <el-input v-if="data.isDbShow" ref="get_Input" v-model="data.pauseContent" autofocus size="mini" @keyup.enter.native="handleInput(node, data)" @blur="handleInput(node, data)" />
+                <el-input v-if="data.isNextDb" ref="get_InputNext" v-model="data.pauseContentNext" autofocus size="mini" @blur="handleInputNext(node, data)" @keyup.enter.native="handleInput(node, data)" />
+                <span>
+                  <el-dropdown v-show="data.del" trigger="hover">
+                    <span class="el-dropdown-link" style="font-weight:bold;z-index:999;">
+                      ···<i class="el-icon--right" />
+                    </span>
+                    <el-dropdown-menu slot="dropdown">
+                      <!-- <el-dropdown-item icon="el-icon-coin" @click.native="addNewNode()">新建节点</el-dropdown-item> -->
+                      <el-dropdown-item icon="el-icon-coin" @click.native="dblclick(data)">修改名称</el-dropdown-item>
+                      <el-dropdown-item icon="el-icon-coin" @click.native="() => append(data)">新建子节点</el-dropdown-item>
+                      <el-dropdown-item icon="el-icon-coin" @click.native="() => deleteNode(data)">删除分组</el-dropdown-item>
+                    </el-dropdown-menu>
+                  </el-dropdown>
+                </span>
+              </span>
+            </el-tree>
+            <el-input v-if="isNewFile" ref="getNewFile" v-model="addFileName" autofocus size="mini" @blur.stop="addFile()" />
+          </div>
+        </div>
+        <div v-show="!isCollapsing" class="collapse-navigation">
+          <div class="expand-collapse">
+            <el-tooltip class="item" effect="dark" content="任务分组" placement="top">
+              <span @click="isCollapsing = !isCollapsing"><i class="el-icon-d-arrow-right" /></span>
+            </el-tooltip>
+          </div>
+          <div class="tips">
+            <div class="lr">
+              <span>任&nbsp;&nbsp;&nbsp;&nbsp;务&nbsp;&nbsp;&nbsp;&nbsp;分&nbsp;&nbsp;&nbsp;&nbsp;组</span>
+            </div>
+          </div>
+        </div>
+        <div class="content">
+          <div class="under-padding">
+            <div v-show="labelDrag.length === 0" class="dataUndisplay">
+              <span>暂无数据~</span>
+            </div>
+            <div v-show="labelDrag" class="set-flex">
+              <div v-for="statusAll in labelDrag" :key="statusAll.status" class="drag-head">
+                <div class="head">
+                  <div class="head-name" :class="{ waitColor: [0, 1, 2, 3, 4, 6, 8, 9].indexOf(statusAll.status) !== -1, 'processColor': [5, 7].indexOf(statusAll.status) !== -1, 'finishColor': [10, 11, 12].indexOf(statusAll.status) !== -1 }">{{ statusAll.statusString }}</div>
+                  <div class="head-score">{{ statusAll.count }}&nbsp;/&nbsp;{{ totalKanBan }}</div>
+                </div>
+              </div>
+            </div>
+            <div v-show="labelDrag" class="set-flex">
+              <div v-for="statusAll in labelDrag" :key="statusAll.status" class="drag">
+                <div v-if="statusAll.count === 0" :key="statusAll.status" class="inner-drag-blank" :class="{ blankColor: statusAll.count === 0 }">
+                  <div class="content-blank">
+                    <span>暂无数据~</span>
+                  </div>
+                </div>
+                <draggable v-model="statusAll.taskInfos" :sort="false" group="statusAll.taskInfos" :move="checkMove" @add="targetRecording(statusAll.status)">
+                  <div v-for="item in statusAll.taskInfos" :key="item.id" class="inner-drag" :class="{ waitColor: [0, 1, 2, 3, 4, 6, 8, 9].indexOf(statusAll.status) !== -1, 'processColor': [5, 7].indexOf(statusAll.status) !== -1, 'finishColor': [10, 11, 12].indexOf(statusAll.status) !== -1 }">
+                    <div class="span-wrap" @click="jumpToReport(item.id)">
+                      <div class="set-reverse">
+                        <span>ID :&nbsp;{{ item.id }}</span>
+                        <div v-show="item.groupName" class="center">
+                          <span>{{ item.groupName }}</span>
+                        </div>
+                      </div>
+                    </div>
+                    <div class="span-wrap" @click="jumpToReport(item.id)">
+                      <span>名称 :&nbsp;{{ item.name }}</span>
+                    </div>
+                    <div class="span-wrap" @click="jumpToReport(item.id)">
+                      <div class="priority" :class="{ 'priority-red':item.priorityString === 'p0', 'priority-orange':item.priorityString === 'p1', 'priority-green':item.priorityString === 'p2', 'priority-blue':item.priorityString === 'p3', 'priority-purple':item.priorityString === 'p4', 'priority-yellow':item.priorityString === 'p5', 'priority-grey':item.priorityString === 'p6' }">
+                        <span>{{ item.priorityString }}</span>
+                      </div>
+                    </div>
+                    <div class="span-wrap" @click="jumpToReport(item.id)">
+                      <div class="set-wrap">
+                        <div v-for="(role,index) in item.nameGroup" :key="index" class="role-color" :class="{ 'priority-orange':( index+1 ) % 7 === 1, 'priority-blue':( index+1 ) % 7 === 2, 'priority-green':( index+1 ) % 7 === 3, 'priority-red':( index+1 ) % 7 === 4, 'priority-purple':( index+1 ) % 7 === 5, 'priority-yellow':( index+1 ) % 7 === 6, 'priority-grey':( index+1 ) % 7 === 0 }">
+                          <span>
+                            {{ role }}
+                          </span>
+                        </div>
+                      </div>
+                    </div>
+                    <div class="span-wrap">
+                      <div class="only-tag">
+                        <!-- <i class="el-icon-price-tag" /> -->
+                        <el-tag
+                          v-for="(tag,index) in item.tagGroup"
+                          :key="index"
+                          type="info"
+                          closable
+                          size="mini"
+                          :disable-transitions="false"
+                          @close.stop="handleClose(tag,item)"
+                        >
+                          <i class="el-icon-price-tag" /> {{ tag }}
+                        </el-tag>
+                        <!-- <el-input v-if="data.isNextDb" ref="get_InputNext" v-model="data.pauseContentNext" autofocus size="mini" @blur="handleInputNext(node, data)" @keyup.enter.native="handleInput(node, data)" /> -->
+                        <el-input
+                          v-if="item.inputVisible"
+                          ref="save_TagInput"
+                          v-model="item.inputValue"
+                          autofocus
+                          class="input-new-tag"
+                          size="mini"
+                          style="width:30%;margin-left:10px;"
+                          @keyup.enter.native="$event.target.blur"
+                          @blur="handleInputConfirm(item)"
+                        />
+                        <el-button v-if="!item.inputVisible" class="button-new-tag" icon="el-icon-plus" size="mini" circle @click="() => showInput(item)" />
+                      </div>
+                    </div>
+                  <!-- <div class="tag-wrap">
+                    <el-tag v-if="item.tag" type="info" size="small" style="margin-left:10px">{{ item.tag }}</el-tag>
+                    <el-tag v-if="item.group" size="small">{{ item.group }}</el-tag>
+                  </div> -->
+                  </div>
+                </draggable>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
     </div>
   </div>
 </template>
@@ -101,39 +263,93 @@
 <script>
 import { taskListGet } from '@/api/defectManage'
 import { bugGetEnum } from '@/api/defectManage' // 下拉菜单data
-import { deleteTaskData } from '@/api/projectPage.js'
+import { deleteTaskData, listMap, updateTaskList, projectGetTypeMap } from '@/api/projectPage.js'
+import { updateComment, deleteComment, listComment, createComment } from '@/api/KanBan.js'
+import draggable from 'vuedraggable'
+// import axios from 'axios'
+
+// let CONSTANT_ID = 9999
 
 export default {
+  name: 'DefectTask',
+  components: {
+    // 调用drag
+    draggable
+  },
   data() {
     return {
+      isPlatformShow: false,
+      isBusinessShow: false,
+      platformTypeStr: [],
+      businessTypeStr: [],
+      defaultExpanded: [],
+      labelDrag: [],
+      isNewFile: false,
+      isClosing: 'none',
       tableData: [],
+      dealWithBusinessDate: [],
+      defaultProps: {
+        children: 'child',
+        label: (data, node) => data.commentInfo.content
+      },
       form: {},
+      addFileName: '',
+      isCollapsing: true,
+      isEmpty: true,
+      formKanBan: {},
       dialogVisible: false,
       bizJson: localStorage.getItem('key'),
       userInformation: localStorage.getItem('username'),
       userNames: localStorage.getItem('realname'),
       queryCode: {},
+      loadingOnlineProcess: false,
       curIndex: 1,
-      pageSize: 20,
+      pageSize: 10,
       total: 0,
+      totalKanBan: 0,
+      pauseTarget: '',
+      pauseFromId: '',
       activeName: 'first',
       pauseId: '',
-      processStatusEnumList: []
+      processStatusEnumList: [],
+      processStatusEnumListKanBan: [],
+      bizOptions: []
+    }
+  },
+  watch: {
+    activeName(newBlock) {
+      newBlock === 'second' ? document.getElementsByClassName('block')[0].style.cssText = 'min-height:0px' : document.getElementsByClassName('block')[0].style.cssText = 'calc(100vh - 100px)'
+    },
+    isCollapsing(newKanbanWidth) {
+      newKanbanWidth === false ? document.getElementsByClassName('content')[0].style.cssText = 'width:93.5%' : document.getElementsByClassName('content')[0].style.cssText = 'width:82.5%'
+    },
+    dealWithBusinessDate(newData, old) {
+      newData.length === 0 ? this.isEmpty = false : this.isEmpty = true
     }
   },
   created() {
     this.bugListSelectBeforeGet()
+    this.forkDown()
   },
   mounted() {
     document.getElementsByClassName('app-main')[0].style.cssText = 'overflow:auto'
+    document.getElementsByClassName('el-tree__empty-block')[0].style.cssText = 'display:none'
+    // document.getElementsByClassName('el-tag__close')[0].style.cssText = 'display:none'
   },
   methods: {
     async bugListSelectBeforeGet() {
+      this.loadingOnlineProcess = true
       await bugGetEnum().then(res => {
         this.processStatusEnumList = res.data.processStatusEnumList
+        this.processStatusEnumListKanBan = res.data.processStatusEnumList
       })
+      const queryListData = {
+        bizId: this.bizJson,
+        pageSize: this.pageSize,
+        curIndex: this.curIndex
+      }
       // 任务list
-      taskListGet({ bizId: this.bizJson }).then(response => {
+      taskListGet(queryListData).then(response => {
         this.tableData = response.data
         this.total = response.total
         this.loadingOnlineProcess = false
@@ -151,16 +367,20 @@ export default {
       queryCode.bizId = localStorage.getItem('key')
       queryCode.pageSize = this.pageSize
       queryCode.curIndex = this.curIndex
+      this.emptyJudge(queryCode)
       taskListGet(queryCode).then(res => {
         res.code === 200 ? this.tableData = res.data : this.errorFun(res.msg)
+        this.total = res.total
       })
     },
-    dataQueryInSearch(queryCode) {
-      queryCode.bizId = localStorage.getItem('key')
-      queryCode.pageSize = this.pageSize
-      queryCode.curIndex = this.curIndex
-      taskListGet(queryCode).then(res => {
+    dataQueryInSearch() {
+      this.form.bizId = parseInt(localStorage.getItem('key'))
+      this.form.pageSize = this.pageSize
+      this.form.curIndex = this.curIndex
+      this.emptyJudge(this.form)
+      taskListGet(this.form).then(res => {
         res.code === 200 ? this.tableData = res.data : this.errorFun(res.msg)
+        this.total = res.total
       })
     },
     createdCode() {
@@ -218,57 +438,344 @@ export default {
       })
       this.dialogVisible = false
     },
-    // // 看板移动更新
-    // checkMove(evt) {
-    //   this.pauseFromId = evt.draggedContext.element.id
-    // },
-    // targetRecording(e) {
-    //   this.pauseTarget = e
-    //   const formTask = { id: this.pauseFromId, status: this.pauseTarget }
-    //   const userData = { id: '', ename: this.userInformation, name: this.userNames }
-    //   const objData = { taskInfo: formTask, user: userData }
-    //   updateTaskList(objData).then(response => {
-    //     if (response.code === 200) {
-    //       this.kanBanDrag()
-    //       this.successFun('operating')
-    //     } else {
-    //       this.errorFun(response.msg)
-    //     }
-    //   })
-    // },
-    // // 看板获取
-    // kanBanDrag() {
-    //   this.loadingOnlineProcess = true
-    //   const initValue = { bizId: this.bizJson }
-    //   listMap(initValue).then((res) => {
-    //     this.labelDrag = res.data
-    //     this.loadingOnlineProcess = false
-    //   })
-    // },
-    // // 标签页研发质量
-    // handleClick() {
-    //   if (this.activeName === 'second') {
-    //     this.kanBanDrag()
-    //   } else if (this.activeName === 'first') {
-    //     this.bugListSelectBeforeGet()
-    //   } else {
-    //     this.errorFun('获取数据失败')
-    //   }
-    // },
-    // // 看板查询
-    // kanBanQuery(e) {
-    //   for (const key in e) {
-    //     if (!e[key]) {
-    //       delete e[key]
-    //     }
-    //   }
-    //   e.bizId = this.bizJson
-    //   this.loadingOnlineProcess = true
-    //   listMap(e).then((res) => {
-    //     this.labelDrag = res.data
-    //     this.loadingOnlineProcess = false
-    //   })
-    // },
+    // 显示隐藏删除图标
+    mouseenter(data) {
+      this.$set(data, 'del', true)
+    },
+    mouseleave(data) {
+      this.$set(data, 'del', false)
+    },
+
+    // 看板移动更新
+    checkMove(evt) {
+      this.pauseFromId = evt.draggedContext.element.id
+    },
+    targetRecording(e) {
+      this.pauseTarget = e
+      const formTask = { id: this.pauseFromId, status: this.pauseTarget }
+      const userData = { id: '', ename: this.userInformation, name: this.userNames }
+      const objData = { taskInfo: formTask, user: userData }
+      updateTaskList(objData).then(response => {
+        if (response.code === 200) {
+          this.kanBanDrag()
+          this.successFun('operating')
+        } else {
+          this.errorFun(response.msg)
+        }
+      })
+    },
+    // 业务线数据获取
+    forkDown() {
+      projectGetTypeMap().then(res => {
+        if (res.code === 200) {
+          this.bizOptions = res.data
+          if (this.bizJson) {
+            this.isPlatformShow = true
+            this.platformTypeStr = this.bizOptions.filter(value => value.code === parseInt(this.bizJson))[0].child
+            this.$set(this.form, 'type', '')
+            this.$set(this.form, 'clientType', '')
+            this.$set(this.formKanBan, 'type', '')
+            this.$set(this.formKanBan, 'clientType', '')
+          } else {
+            this.isPlatformShow = false
+            this.isBusinessShow = false
+          }
+        } else {
+          this.errorFun('业务线数据获取失败')
+        }
+      })
+    },
+    // 业务线取子数据
+    clickChangeBusiness(e) {
+      if (e && this.platformTypeStr.filter(value => value.code === e)[0].child) {
+        this.isBusinessShow = true
+        this.businessTypeStr = this.platformTypeStr.filter(value => value.code === e)[0].child
+        this.$set(this.form, 'clientType', '')
+        this.$set(this.formKanBan, 'clientType', '')
+      } else {
+        this.isBusinessShow = false
+      }
+    },
+    clickChangeModule(e) {
+      console.log(e)
+      if (!e) {
+        this.isBusinessShow = false
+      }
+    },
+    // 看板获取
+    kanBanDrag() {
+      this.loadingOnlineProcess = true
+      const initValue = { bizId: this.bizJson }
+      listMap(initValue).then((res) => {
+        res.code === 200 ? this.labelDrag = this.bubble(res.data) : this.errorFun(res.msg)
+        this.loadingOnlineProcess = false
+        // HTMLCollection 如何便利呢
+        // console.log(document.getElementsByClassName('el-tag__close'))
+        // document.getElementsByClassName('el-tag__close').map((eachHtml) => {
+        //   eachHtml.style.cssText = 'display:none'
+        // })
+      })
+    },
+    // 标签删除
+    handleClose(tag, item) {
+      const afterDeleteArr = item.tagGroup.filter((eachData) => eachData !== tag)
+      this.$confirm('是否确认删除', '确认信息', {
+        distinguishCancelAndClose: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消'
+      }).then(() => {
+        const sendData = { id: item.id, tag: afterDeleteArr.join(',') }
+        const userData = { id: '', ename: this.userInformation, name: this.userNames }
+        const objData = { taskInfo: sendData, user: userData }
+        updateTaskList(objData).then(res => {
+          this.kanBanDrag()
+        })
+      }).catch(action => {
+        this.$message({ type: 'success', message: '已取消' })
+      })
+    },
+    // 失去焦点执行
+    handleInputConfirm(item) {
+      if (item.inputValue === undefined) {
+        item.inputVisible = false
+        return
+      }
+      item.tagGroup.push(item.inputValue)
+      const sendData = { id: item.id, tag: item.tagGroup.join(',') }
+      const userData = { id: '', ename: this.userInformation, name: this.userNames }
+      const objData = { taskInfo: sendData, user: userData }
+      updateTaskList(objData).then((res) => {
+        this.$set(item, 'inputVisible', false)
+        this.kanBanDrag()
+      })
+    },
+    // 添加标签
+    showInput(item) {
+      this.$set(item, 'inputVisible', true)
+      this.$nextTick(() => {
+        // setTimeout(() => {
+        //   that.$refs.save_TagInput.focus()
+        // })
+        this.$refs.save_TagInput[0].focus() // 真的神奇。。。
+      })
+    },
+    // 导航栏获取
+    navigationGet() {
+      listComment({ bizId: this.bizJson, type: 1 }).then((res) => {
+        const reduceNa = (arr) => { // modules和child
+          arr.forEach((each) => {
+            each.id = each.commentInfo.id
+            each.spanAbsolute = true
+            if (each.child) {
+              each.child = reduceNa(each.child)
+            }
+          })
+          return arr
+        }
+        res.code === 200 ? this.dealWithBusinessDate = reduceNa(res.data) : this.errorFun(res.msg)
+        // this.dealWithBusinessDate === [] ? this.isEmpty = false : this.isEmpty = true
+        // console.log(this.isEmpty)
+      })
+    },
+    // 冒泡数量从高到低 和 分组
+    bubble(arr) {
+      let res = Object.assign([], arr)
+      const max = res.length - 1
+      for (let j = 0; j < max; j++) {
+        // 声明一个变量,作为标志位
+        let done = true
+        for (let i = 0; i < max - j; i++) {
+          if (res[i].count < res[i + 1].count) {
+            var temp = res[i]
+            res[i] = res[i + 1]
+            res[i + 1] = temp
+            done = false
+          }
+        }
+        if (done) {
+          break
+        }
+      }
+      // 自己处理吧 (^_^)
+      res = res.map(eachData => ({
+        ...eachData,
+        taskInfos: eachData.taskInfos.map(detail => ({
+          ...detail,
+          tagGroup: [
+            ...(detail.tag ? detail.tag.split(',').map(str => str.trim()) : [])
+          ],
+          nameGroup: [
+            ...(detail.pmList ? detail.pmList.split(',').map(str => str.trim()) : []),
+            ...(detail.qaList ? detail.qaList.split(',').map(str => str.trim()) : []),
+            ...(detail.rdList ? detail.rdList.split(',').map(str => str.trim()) : [])
+          ]
+        }))
+      }))
+      this.totalKanBan = res.reduce((sumSoFar, item) => sumSoFar + item.count, 0)
+      return res
+    },
+    // 标签页研发质量
+    handleClick() {
+      if (this.activeName === 'second') {
+        this.isBusinessShow = false
+        this.kanBanDrag()
+        this.navigationGet()
+      } else if (this.activeName === 'first') {
+        this.isBusinessShow = false
+        this.bugListSelectBeforeGet()
+      } else {
+        this.errorFun('获取数据失败')
+      }
+    },
+    // 新增子节点
+    append(data) {
+      const newChild = { id: data.id, commentInfo: { content: '新建文件夹' }, child: [] }
+      if (!data.child) {
+        this.$set(data, 'child', [])
+      }
+      // this.$nextTick(() => {
+      //   data.child.push(newChild)
+      // })
+      data.child.push(newChild)
+      this.defaultExpanded.push(data.id)
+      this.$set(newChild, 'pauseContentNext', newChild.commentInfo.content)
+      this.$set(newChild, 'isNextDb', true)
+      this.$set(newChild, 'isDbShow', false)
+      this.$set(newChild, 'spanAbsolute', false)
+      this.$nextTick(() => {
+        setTimeout(() => {
+          this.$refs.get_InputNext.focus()
+        })
+        this.$refs.get_InputNext.focus()
+      })
+    },
+    // 创建下级节点
+    handleInputNext(node, data) {
+      if (data.pauseContentNext === '') {
+        this.$set(data, 'isNextDb', false)
+        this.$set(data, 'isDbShow', false)
+        this.$set(data, 'spanAbsolute', true)
+        return
+      }
+      const sendData = { bizId: this.bizJson, type: 1, fatherId: data.id, content: data.pauseContentNext }
+      const userData = { id: '', ename: this.userInformation, name: this.userNames }
+      const objData = { commentInfo: sendData, user: userData }
+      createComment(objData).then((res) => {
+        this.$set(data, 'isNextDb', false)
+        this.$set(data, 'isDbShow', false)
+        this.$set(data, 'spanAbsolute', true)
+        this.navigationGet()
+      })
+    },
+    // 删除节点
+    deleteNode(data) {
+      this.$confirm('是否确认删除', '确认信息', {
+        distinguishCancelAndClose: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消'
+      }).then(() => {
+        const userData = { bizId: this.bizJson, id: '', ename: this.userInformation, name: this.userNames }
+        const objData = { user: userData }
+        deleteComment(data.commentInfo.id, objData).then(res => {
+          this.defaultExpanded.push(data.commentInfo.fatherId)
+          this.navigationGet()
+        })
+      }).catch(action => {
+        this.$message({ type: 'success', message: '已取消' })
+      })
+    },
+    // 新建最外级节点
+    addNewNode() {
+      this.isEmpty = true
+      this.isNewFile = true
+      this.$nextTick(() => {
+        this.$refs.getNewFile.focus()
+      })
+    },
+    addFile() {
+      if (this.addFileName === '') {
+        this.isNewFile = false
+        this.isEmpty = false
+        return
+      }
+      const sendData = { bizId: this.bizJson, type: 1, fatherId: 0, content: this.addFileName }
+      const userData = { id: '', ename: this.userInformation, name: this.userNames }
+      const objData = { commentInfo: sendData, user: userData }
+      createComment(objData).then((res) => {
+        this.isNewFile = false
+        this.navigationGet()
+        this.addFileName = ''
+      })
+    },
+    // 双击编辑
+    dblclick(data) {
+      this.$set(data, 'pauseContent', data.commentInfo.content)
+      this.$set(data, 'isDbShow', true)
+      this.$set(data, 'isNextDb', false)
+      this.$set(data, 'spanAbsolute', false)
+      this.$nextTick(() => {
+        this.$refs.get_Input.focus()
+      })
+    },
+    // 看板查询
+    kanBanQuery(e) {
+      this.emptyJudge(e)
+      e.bizId = this.bizJson
+      this.loadingOnlineProcess = true
+      listMap(e).then((res) => {
+        res.code === 200 ? this.labelDrag = this.bubble(res.data) : this.errorFun(res.msg)
+        this.loadingOnlineProcess = false
+      })
+    },
+    // 接口不接受空值处理
+    emptyJudge(obj) {
+      for (const key in obj) {
+        if (obj[key] === '') {
+          delete obj[key]
+        }
+      }
+    },
+    // 看板跳转
+    jumpToReport(id) {
+      this.$router.push({ name: '任务查看', query: { id: id }})
+    },
+    // tree
+    handleNodeClick(data) {
+      if (data.commentInfo.fatherId === 0) {
+        this.kanBanDrag()
+      } else {
+        this.loadingOnlineProcess = true
+        const initValue = { bizId: this.bizJson, group: data.commentInfo.id }
+        listMap(initValue).then((res) => {
+          res.code === 200 ? this.labelDrag = this.bubble(res.data) : this.errorFun(res.msg)
+          this.loadingOnlineProcess = false
+        // HTMLCollection 如何便利呢
+        // console.log(document.getElementsByClassName('el-tag__close'))
+        // document.getElementsByClassName('el-tag__close').map((eachHtml) => {
+        //   eachHtml.style.cssText = 'display:none'
+        // })
+        })
+      }
+    },
+    // 双击编辑
+    handleInput(node, data) {
+      if (data.pauseContent === data.commentInfo.content) {
+        this.$set(data, 'isDbShow', false)
+        this.$set(data, 'isNextDb', false)
+        this.$set(data, 'spanAbsolute', true)
+        return
+      }
+      const sendData = { bizId: this.bizJson, type: 1, id: data.commentInfo.id, content: data.pauseContent }
+      const userData = { id: '', ename: this.userInformation, name: this.userNames }
+      const objData = { commentInfo: sendData, user: userData }
+      updateComment(objData).then((res) => {
+        this.defaultExpanded.push(data.commentInfo.fatherId)
+        this.$set(data, 'isDbShow', false)
+        this.$set(data, 'isNextDb', false)
+        this.$set(data, 'spanAbsolute', true)
+        this.navigationGet()
+      })
+    },
     handleCurrentChange(curIndex) {
       this.curIndex = curIndex
       this.dataQueryInSearch()
@@ -293,17 +800,17 @@ export default {
 
   .set-background
     background-color #F2F3F6
-    display flex
-    justify-content center
+    padding 20px
     min-width 900px
+    min-height calc(100vh - 50px)
     .block
       background-color rgba(255,255,255,1)
       box-shadow 0px 0px 11px 0px rgba(238,240,245,1)
       border-radius 7px
-      width 96%
-      margin 25px 0
+      width 100%
+      // margin-bottom 25px
       padding 10px 20px
-      min-height calc(100vh - 100px)
+      min-height calc(100vh - 90px)
     .block >>> .el-tabs__nav-wrap::after
       background-color white
     .block >>> .el-tabs__item
@@ -318,11 +825,351 @@ export default {
       background-color #F0F2F4 !important
     .set-between
       display flex
+    .set-between:first-child
+      width 80%
     .set-between >>> .el-button
       height 36px
     .set-between >>> .el-form-item
       display flex
       margin-right -35px
-    .set-locate
-      margin-top 15px
+    .set-between-kanban
+      display flex
+      align-items center
+      margin-bottom 20px
+    .set-between-kanban:first-child
+      width 80%
+    .set-between-kanban >>> .el-button
+      height 36px
+    .set-between-kanban >>> .el-form-item
+      display flex
+      margin-bottom 0px !important
+      margin-right -35px
+    .navigation-content
+      width 100%
+      display flex
+      justify-content space-between
+      margin-top 20px
+      height calc(100vh - 254px)
+      .navigation
+        background-color rgba(255,255,255,1)
+        box-shadow 0px 0px 11px 0px rgba(238,240,245,1)
+        border-radius 7px
+        width 16%
+        height 100%
+        .collapse
+          height 30px
+          padding 4px 10px 0 0
+          display flex
+          flex-direction row-reverse
+          font-size 14px
+          font-weight 400
+          color rgba(111,124,147,1)
+          line-height 35px
+          span
+            cursor pointer
+        .scroll-navigate
+          overflow-x scroll
+          height calc(100% - 30px)
+          // .span_el
+          //   display block
+          //   overflow hidden
+          //   /* white-space: nowrap; */
+          //   text-overflow ellipsis
+          .empty-add
+            width 100%
+            height calc(100% - 30px)
+            display flex
+            align-items center
+            justify-content center
+            span
+              color rgba(111,124,147,1)
+              font-size 14px
+              padding-left 5px
+              cursor pointer
+            .el-icon-circle-plus
+              opacity 0.4
+              cursor pointer
+          .custom-tree-node
+            width 100%
+            font-size 14px
+            display flex
+            align-items center
+            justify-content space-between
+            font-size 14px
+            // padding-right 25px
+          .el-button--text
+            margin-right 10px
+      .navigation >>> .el-tree-node__content
+        height 30px !important
+      .navigation >>> .el-tree-node__children
+        opacity 0.9
+      .navigation >>> .el-tree-node__expand-icon
+        font-size 14px
+        color black
+        opacity 0.7
+      .navigation >>> .el-tree-node__expand-icon.is-leaf
+        color transparent !important
+        cursor default !important
+      .collapse-navigation
+        background-color rgba(255,255,255,1)
+        box-shadow 0px 0px 11px 0px rgba(238,240,245,1)
+        border-radius 7px
+        width 5%
+        height 100%
+        .expand-collapse
+          display flex
+          justify-content center
+          height 30px
+          font-size 14px
+          font-weight 400
+          color rgba(111,124,147,1)
+          line-height 35px
+          span
+            cursor pointer
+        .tips
+          margin-top 130px
+          display flex
+          justify-content center
+          width 100%
+          height 200px
+          .lr
+            height 100%
+            span
+              writing-mode vertical-rl
+              font-size 15px
+              font-weight 400
+              color rgba(111,124,147,1)
+              line-height 35px
+      .content
+        background-color rgba(255,255,255,1)
+        box-shadow 0px 0px 11px 0px rgba(238,240,245,1)
+        border-radius 7px
+        width 82.5%
+        height 100%
+        padding 20px
+        .under-padding
+          width 100%
+          height 100%
+          overflow-x scroll
+          .dataUndisplay
+            width 100%
+            height 100%
+            display flex
+            justify-content center
+            align-items center
+            span
+              font-weight 400
+              color #6f7c93
+              font-size 14px
+              line-height 20px
+          .set-flex
+            width 3880px
+            display flex
+            justify-content space-between
+            .drag-head
+              width 280px
+              border-radius 7px 7px 0 0
+              background-color #ECECEC
+              box-shadow 0px 0px 11px 0px #ececec
+              height fit-content
+              // overflow scroll
+              .head
+                height 50px
+                display flex
+                justify-content center
+                align-items center
+                padding-top 10px
+                .head-name
+                  font-size 14px
+                  font-weight 400
+                  line-height 35px
+                  margin-right 5px
+                .waitColor
+                  color #F56C6C
+                .processColor
+                  color #FB9616
+                .finishColor
+                  color #00C9AE
+                .head-score
+                  font-size 14px
+                  font-weight 400
+                  line-height 35px
+                  margin-left 5px
+            .drag
+              width 280px
+              border-radius 0 0 7px 7px
+              background-color #ECECEC
+              box-shadow 0px 0px 11px 0px #ececec
+              height fit-content
+              max-height 56.4vh
+              overflow scroll
+              .inner-drag
+                width 89%
+                margin 10px auto 0 auto
+                background-color white
+                border-radius 4px
+                padding 10px 10px 4px 10px
+                border-left-width 4px
+                border-left-style solid
+                &.waitColor
+                  border-left-color #F56C6C
+                &.processColor
+                  border-left-color #FB9616
+                &.finishColor
+                  border-left-color #00C9AE
+                .span-wrap
+                  width 100%
+                  // margin-bottom 5px
+                  span
+                    font-size 13px
+                    font-weight 400
+                    color rgba(51,59,74,1)
+                    line-height 20px
+                  .priority
+                    width 18px
+                    display flex
+                    align-items center
+                    justify-content center
+                    height 18px
+                    margin-top 3px
+                    border-radius 4px
+                    &.priority-red
+                      background-color #F56C6C
+                    &.priority-orange
+                      background-color #FB9616
+                    &.priority-green
+                      background-color #7DCB72
+                    &.priority-blue
+                      background-color #73C5FA
+                    &.priority-purple
+                      background-color #AEB4FF
+                    &.priority-yellow
+                      background-color yellow
+                    &.priority-grey
+                      background-color grey
+                    span
+                      color rgba(255,255,255,1)
+                      transform scale(0.8)
+                      font-size 12px
+                  .set-wrap
+                    width 100%
+                    display flex
+                    flex-wrap wrap
+                    .role-color
+                      display flex
+                      align-items center
+                      justify-content center
+                      height 18px
+                      margin-top 6px
+                      border-radius 4px
+                      margin-right 8px
+                      padding 0 3px 0 3px
+                      &.priority-red
+                        background-color #F56C6C
+                      &.priority-orange
+                        background-color #FB9616
+                      &.priority-green
+                        background-color #7DCB72
+                      &.priority-blue
+                        background-color #73C5FA
+                      &.priority-purple
+                        background-color #AEB4FF
+                      &.priority-yellow
+                        background-color yellow
+                      &.priority-grey
+                        background-color grey
+                      span
+                        color rgba(255,255,255,1)
+                        transform scale(0.8)
+                        font-size 12px
+                  .only-tag
+                    width 100%
+                    display flex
+                    flex-wrap wrap
+                    margin-top 6px
+                    span
+                      font-size 12px
+                    .el-tag
+                      margin 0px 10px 6px 0px
+                      display flex
+                      // align-items center
+                      // justify-content center
+                      // height 28px
+                    .button-new-tag
+                      // margin-left 10px
+                      padding 3px
+                      height 20px
+                      background-color #f4f4f5
+                      // height 25px
+                      // width 25px
+                      display flex
+                      // align-items center
+                      // justify-content center
+                      // height 32px
+                      // line-height 30px
+                      // padding-top 0
+                      // padding-bottom 0
+                    .input-new-tag
+                      // width 90px
+                      // height 25px
+                      // margin-left 10px
+                      // vertical-align bottom
+                    .input-new-tag >>> .el-input__inner
+                      height 20px
+                      line-height 20px
+                    .el-icon-price-tag
+                      margin-right 4px
+                      padding-top 3px
+                      font-size 12px
+                      transform rotate(-45deg)
+                  .set-reverse
+                    width 100%
+                    display flex
+                    justify-content space-between
+                    span
+                      font-size 13px
+                      font-weight 400
+                      color rgba(51,59,74,1)
+                      line-height 20px
+                    .center
+                      display flex
+                      align-items center
+                      justify-content center
+                      border-radius 4px
+                      border 1px solid #ddd
+                      width fit-content
+                      height 18px
+                      padding 0 6px 0 6px
+                      span
+                        color rgba(151,151,151,1)
+                        transform scale(0.7)
+                        font-size 12px
+                .tag-wrap
+                  margin-top 15px
+                  display flex
+                  flex-direction row-reverse
+              .inner-drag:last-child
+                width 89%
+                margin 10px auto
+                background-color white
+                border-radius 4px
+              .inner-drag-blank
+                width 89%
+                margin 10px auto
+                background-color white
+                border-radius 4px
+                padding 10px
+                border-left-width 4px
+                border-left-style solid
+                &.blankColor
+                  border-left-color #A7AEBC
+                .content-blank
+                  display flex
+                  justify-content center
+                  align-items center
+                  width 100%
+                  height 60px
+                  span
+                    color rgba(167,174,188,1)
+                    font-size 12px
 </style>

+ 3 - 3
src/views/virtualDevices/HMvehicle.vue

@@ -23,9 +23,9 @@
             </el-select>
           </div>
           <div class="set-between">
-            <el-button type="primary" size="medium" plain @click="dataQuery(queryCode)">搜索</el-button>
-            <el-button type="primary" size="medium" plain @click="createdCode()">新增</el-button>
-            <el-button type="primary" size="medium" plain @click="oneKeyCreate()">一键创建</el-button>
+            <el-button type="primary" size="medium" @click="dataQuery(queryCode)">搜索</el-button>
+            <el-button type="primary" size="medium" @click="createdCode()">新增</el-button>
+            <el-button type="primary" size="medium" @click="oneKeyCreate()">一键创建</el-button>
           </div>
         </el-form>
         <div class="set-locate">