taskIndex.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207
  1. <template>
  2. <div
  3. class="bgborder"
  4. style="background-color:#F2F3F6;min-height:calc(100vh - 80px);padding:0 0px 10px 10px"
  5. >
  6. <div class="stylus-head">
  7. <mainTitle
  8. title="任务"
  9. btn-text="新建任务"
  10. :tab-show="true"
  11. @btn-handle="open_created"
  12. @change-tab="changeTab"
  13. />
  14. <div v-if="nowTab === 'charts'" class="chartView">
  15. <chartView
  16. :data="chartData"
  17. :type-option-list="typeOptionList"
  18. :chart-search-data="form_task"
  19. @search="get_charts()"
  20. @changeList="(code) => get_chartListDetial(code)"
  21. >
  22. <div slot="searchBox">
  23. <div class="Layout">
  24. <div class="Layout">
  25. <div class="chartSearchTitle">模块</div>
  26. <el-cascader
  27. v-model="form_task.moduleIds"
  28. size="small"
  29. clearable
  30. collapse-tags
  31. :props="props"
  32. :options="business_platform_Modular"
  33. placeholder="请选择"
  34. style="width:77% !important;"
  35. @change="get_charts()"
  36. />
  37. </div>
  38. <span
  39. class="screen"
  40. style="text-align:right; width: auto"
  41. @click="showChartModal = true"
  42. >更多筛选</span>
  43. </div>
  44. </div>
  45. </chartView>
  46. </div>
  47. <div v-if="nowTab === 'list'" class="search_box">
  48. <div class="Layout" style="padding: 5px 0 0 15px">
  49. <div>
  50. <el-form :model="form_task" class="Layout">
  51. <div class="Layout_flex_end item">
  52. <div class="queryName">任务名称</div>
  53. <el-input
  54. v-model="form_task.name"
  55. size="small"
  56. clearable
  57. class="input"
  58. placeholder="请输入标题或ID或望岳ID"
  59. @change="get_taskList()"
  60. />
  61. </div>
  62. <div class="Layout item">
  63. <div class="queryName">状态</div>
  64. <el-select
  65. v-model="form_task.statusList"
  66. size="small"
  67. class="input"
  68. multiple
  69. clearable
  70. filterable
  71. placeholder="请选择"
  72. @change="get_taskList()"
  73. >
  74. <el-option
  75. v-for="item in daStatus"
  76. :key="item.value"
  77. :label="item.label"
  78. :value="item.value"
  79. />
  80. </el-select>
  81. </div>
  82. <div class="Layout item">
  83. <div class="queryName">模块</div>
  84. <el-cascader
  85. v-model="form_task.moduleIds"
  86. size="small"
  87. class="input"
  88. clearable
  89. collapse-tags
  90. :props="props"
  91. :options="business_platform_Modular"
  92. placeholder="请选择"
  93. @change="get_taskList()"
  94. />
  95. </div>
  96. </el-form>
  97. </div>
  98. <span class="screen" @click="showSelect">{{ goodName }}</span>
  99. </div>
  100. <div v-show="DetailedScreening" class="stylus-more">
  101. <div>
  102. <div class="Layout" style="margin: 15px 0;">
  103. <el-form :model="form_task" class="flex_start">
  104. <div class="Layout item">
  105. <div class="queryName">所属项目</div>
  106. <el-select
  107. v-model="form_task.projectId"
  108. size="small"
  109. class="input"
  110. clearable
  111. filterable
  112. placeholder="请选择"
  113. >
  114. <el-option
  115. v-for="item in projectList"
  116. :key="item.value"
  117. :label="item.label"
  118. :value="item.value"
  119. />
  120. </el-select>
  121. </div>
  122. <div class="Layout item">
  123. <div class="queryName">所属需求</div>
  124. <el-select
  125. v-model="form_task.requireId"
  126. size="small"
  127. class="input"
  128. clearable
  129. filterable
  130. placeholder="请选择"
  131. >
  132. <el-option
  133. v-for="item in demandList"
  134. :key="item.value"
  135. :label="item.label"
  136. :value="item.value"
  137. />
  138. </el-select>
  139. </div>
  140. <div class="Layout item">
  141. <div class="queryName">来自望岳</div>
  142. <el-select
  143. v-model="form_task.isFromDpm"
  144. size="small"
  145. class="input"
  146. clearable
  147. filterable
  148. placeholder="请选择"
  149. >
  150. <el-option
  151. v-for="item in isFromDpmList"
  152. :key="item.value"
  153. :label="item.label"
  154. :value="item.value"
  155. />
  156. </el-select>
  157. </div>
  158. </el-form>
  159. </div>
  160. <div class="Layout" style="margin: 15px 0;">
  161. <el-form :model="form_task" class="flex_start">
  162. <div class="Layout item">
  163. <div class="queryName">优先级</div>
  164. <el-select
  165. v-model="form_task.priority"
  166. size="small"
  167. class="input"
  168. clearable
  169. filterable
  170. placeholder="请选择"
  171. >
  172. <el-option
  173. v-for="item in arr_priority"
  174. :key="item.value"
  175. :label="item.label"
  176. :value="item.value"
  177. />
  178. </el-select>
  179. </div>
  180. <div class="Layout item">
  181. <div class="queryName">负责人</div>
  182. <el-select
  183. v-model="form_task.PersonInCharge"
  184. class="input"
  185. clearable
  186. filterable
  187. remote
  188. placeholder="请输入姓名或邮箱前缀"
  189. :remote-method="remoteMethod"
  190. :loading="loading"
  191. size="small"
  192. >
  193. <el-option
  194. v-for="item in options"
  195. :key="item.idap"
  196. :label="item.name"
  197. :value="test2(item, 0)"
  198. >
  199. <div class="flex_start">
  200. <div class="deptName">{{ item.deptName }}</div>
  201. <div style="min-width:80px">{{ item.name }}</div>
  202. <div class="deptName">{{ item.idap }}</div>
  203. </div>
  204. </el-option>
  205. </el-select>
  206. </div>
  207. <div class="Layout item">
  208. <div class="queryName">健康状态</div>
  209. <el-select
  210. v-model="form_task.stage"
  211. size="small"
  212. class="input"
  213. clearable
  214. filterable
  215. placeholder="请选择"
  216. >
  217. <el-option
  218. v-for="item in healthStage"
  219. :key="item.value"
  220. :label="item.label"
  221. :value="item.value"
  222. />
  223. </el-select>
  224. </div>
  225. </el-form>
  226. </div>
  227. <div class="Layout" style="margin: 15px 0;">
  228. <el-form :model="form_task" class="flex_start">
  229. <div class="Layout item">
  230. <div class="queryName">创建人</div>
  231. <el-select
  232. v-model="form_task.creater"
  233. class="input"
  234. clearable
  235. filterable
  236. remote
  237. placeholder="请输入姓名或邮箱前缀"
  238. :remote-method="remoteMethod"
  239. :loading="loading"
  240. size="small"
  241. style="width: 82%;"
  242. >
  243. <el-option
  244. v-for="item in options"
  245. :key="item.idap"
  246. :label="item.name"
  247. :value="test2(item, 0)"
  248. >
  249. <div class="flex_start">
  250. <div class="deptName">{{ item.deptName }}</div>
  251. <div style="min-width:80px">{{ item.name }}</div>
  252. <div class="deptName">{{ item.idap }}</div>
  253. </div>
  254. </el-option>
  255. </el-select>
  256. </div>
  257. <div class="Layout item">
  258. <div class="queryName">是否免测</div>
  259. <el-select
  260. v-model="form_task.notest"
  261. size="small"
  262. class="input"
  263. clearable
  264. filterable
  265. placeholder="请选择"
  266. >
  267. <el-option
  268. v-for="item in isNoTest"
  269. :key="item.value"
  270. :label="item.label"
  271. :value="item.value"
  272. />
  273. </el-select>
  274. </div>
  275. </el-form>
  276. </div>
  277. <div class="Layout" style="margin: 15px 0;">
  278. <el-form :model="form_task" class="flex_start">
  279. <div class="Layout item">
  280. <div class="queryName">创建日期</div>
  281. <el-date-picker
  282. v-model="form_task.date"
  283. type="daterange"
  284. align="right"
  285. unlink-panels
  286. range-separator="至"
  287. start-placeholder="开始日期"
  288. end-placeholder="结束日期"
  289. size="small"
  290. class="input"
  291. style="min-width: 458px"
  292. value-format="yyyy-MM-dd HH:mm:ss"
  293. :default-time="['00:00:00','23:59:59']"
  294. :picker-options="pickerOptions"
  295. />
  296. </div>
  297. </el-form>
  298. </div>
  299. <div align="right">
  300. <el-button type="text" @click="showSaveSearch = true">保存筛选项</el-button>
  301. <el-button type="primary" size="mini" @click="get_taskList(form_task)">筛 选</el-button>
  302. <el-button size="mini" @click="query_Reset">重 置</el-button>
  303. </div>
  304. </div>
  305. </div>
  306. <div v-if="filterList.length && filterList.length > 0" class="filter">
  307. <div class="filterWrap">
  308. <div class="title">我的过滤器:</div>
  309. <div class="itemBox">
  310. <el-tag
  311. v-for="item in filterList"
  312. :key="item.id"
  313. class="itemFilter"
  314. @click="getFilterItem(item.id)"
  315. >{{ item.name }}</el-tag>
  316. </div>
  317. </div>
  318. <div class="btn">
  319. <span @click.stop="showEditSearch = true">管理过滤器</span>
  320. </div>
  321. </div>
  322. </div>
  323. </div>
  324. <div class="stylus-content">
  325. <div v-if="nowTab === 'charts'" class="subtitle">{{ tableTitle }}</div>
  326. <el-table
  327. v-loading="table_loading"
  328. :data="task_table"
  329. style="width: 100%;"
  330. highlight-current-row
  331. :header-cell-style="{ 'background': nowTab === 'charts' ? '#F7F7F7' : '#fff', 'color':'rgba(74,74,74,1)','font-size':'14px','font-weight':'500' }"
  332. :cell-style="{ 'font-size':'14px','color':'rgba(102,102,102,1)' }"
  333. size="small"
  334. show-overflow-tooltip="true"
  335. >
  336. <el-table-column label="优先级" width="90" prop="priority" sortable align="right">
  337. <template slot-scope="scope">
  338. <div
  339. class="div_priority"
  340. :style="{background: priorityColors[scope.row.priority]}"
  341. >{{ scope.row.priorityString }}</div>
  342. </template>
  343. </el-table-column>
  344. <el-table-column label="任务名称" min-width="250" show-overflow-tooltip align="left">
  345. <template slot-scope="scope">
  346. <span style="font-size: 12px;color: rgba(167,174,188,1);">
  347. {{ scope.row.taskIdSting }}
  348. <span
  349. v-if="scope.row.tagNotification !== null && scope.row.status !== -2"
  350. :class="{
  351. 'tagNotification': scope.row.tagType === 0,
  352. 'tagNotification1': scope.row.tagType === 1
  353. }"
  354. >{{ scope.row.tagNotification }}</span>
  355. <span v-if="scope.row.status === -2" class="tagNotification1">{{ 'hold' }}</span>
  356. </span>
  357. <br>
  358. <span class="stylus-hover" @click="link_task(scope.row.id)">{{ scope.row.name }}</span>
  359. </template>
  360. </el-table-column>
  361. <el-table-column label="状态" min-width="150" align="center" show-overflow-tooltip>
  362. <template slot-scope="scope">
  363. <el-select
  364. v-if="nowTab === 'charts'"
  365. v-model="scope.row.status"
  366. :size="size"
  367. placeholder
  368. @change="(e) => statusChange(e, scope.row.id)"
  369. >
  370. <el-option
  371. v-for="o in scope.row.availableStatusList"
  372. :key="o.code"
  373. :label="o.name"
  374. :value="o.code"
  375. />
  376. </el-select>
  377. <span v-else>{{ scope.row.statusString }}</span>
  378. </template>
  379. </el-table-column>
  380. <el-table-column label="健康状态" width="150" align="center" show-overflow-tooltip>
  381. <template slot-scope="scope">{{ scope.row.stageString }}</template>
  382. </el-table-column>
  383. <el-table-column label="开发负责人" min-width="100" align="center">
  384. <template
  385. slot-scope="scope"
  386. >{{ scope.row.rdObject !== null? scope.row.rdObject.name: '' }}</template>
  387. </el-table-column>
  388. <el-table-column label="测试负责人" min-width="100" align="center">
  389. <template slot-scope="scope">{{ scope.row.qaObject !== null?scope.row.qaObject.name: '' }}</template>
  390. </el-table-column>
  391. <el-table-column label="所属模块" width="150" align="center" show-overflow-tooltip>
  392. <template slot-scope="scope">{{ scope.row.moduleInfoName }}</template>
  393. </el-table-column>
  394. <el-table-column label="是否免测" min-width="80" align="center">
  395. <template slot-scope="scope">{{ scope.row.noTestString }}</template>
  396. </el-table-column>
  397. <el-table-column label="缺陷数量" width="250" align="center" show-overflow-tooltip>
  398. <template slot-scope="scope">{{ scope.row.bugCount }}</template>
  399. </el-table-column>
  400. <el-table-column label="所属需求" min-width="250" align="center" show-overflow-tooltip>
  401. <template slot-scope="scope">{{ scope.row.requireName }}</template>
  402. </el-table-column>
  403. <el-table-column label="所属项目" min-width="250" align="center" show-overflow-tooltip>
  404. <template slot-scope="scope">{{ scope.row.projectName }}</template>
  405. </el-table-column>
  406. <el-table-column label="创建人" min-width="120" align="center" show-overflow-tooltip>
  407. <template slot-scope="scope">{{ scope.row.createObject.name }}</template>
  408. </el-table-column>
  409. <el-table-column label="创建日期" min-width="120" align="center" show-overflow-tooltip>
  410. <template slot-scope="scope">{{ scope.row.createTime }}</template>
  411. </el-table-column>
  412. </el-table>
  413. <div align="right">
  414. <el-pagination
  415. background
  416. :current-page="currentPage"
  417. :page-sizes="[15,30,45,total]"
  418. :page-size="pageSize"
  419. layout="total, sizes, prev, pager, next, jumper"
  420. :total="total"
  421. @size-change="handleSizeChange"
  422. @current-change="handleCurrentChange"
  423. />
  424. </div>
  425. </div>
  426. <!-- 弹窗 -->
  427. <openDialog v-if="dialog_open" ref="task_createdUpdata" />
  428. <normal-dialog
  429. :show-dialog="showSaveSearch"
  430. :title="'保存筛选项'"
  431. :width="'35%'"
  432. @confirm="saveSearch('searchForm')"
  433. @cancel="showSaveSearch=false"
  434. >
  435. <div v-if="showSaveSearch" class="file-dialog">
  436. <el-form ref="searchForm" :model="searchForm" :rules="searchFormRules" label-width="100px">
  437. <el-form-item label="过滤器名称" prop="name">
  438. <el-input v-model="searchForm.name" placeholder="不超过50个字符" />
  439. </el-form-item>
  440. </el-form>
  441. </div>
  442. </normal-dialog>
  443. <normal-dialog
  444. :show-footer="false"
  445. :show-dialog="showEditSearch"
  446. :title="'管理过滤器'"
  447. :width="'65%'"
  448. @cancel="showEditSearch=false"
  449. >
  450. <filter-list :show-filter="showEditSearch" :filter-type="2" @deleteFilter="deleteFilter" />
  451. </normal-dialog>
  452. <filterModal
  453. title="筛选项"
  454. :show-dialog="showChartModal"
  455. @reset="query_Reset"
  456. @cancel="showChartModal = false"
  457. @confirm="filterModalConfirm"
  458. >
  459. <div>
  460. <chartSearchForm
  461. :data="chartSearchFormRenderData"
  462. :loading="loading"
  463. :styles="{ marginBottom: '15px', width: '380px' }"
  464. @change="chartSearchFormChange"
  465. @getOption="(key, q, utilName) => remoteMethod(q)"
  466. />
  467. </div>
  468. </filterModal>
  469. </div>
  470. </template>
  471. <script>
  472. const _ = require('lodash')
  473. import { EncryptId } from '@/utils/crypto-js.js'
  474. import { mapGetters } from 'vuex'
  475. import {
  476. taskList,
  477. configShowTaskEnum,
  478. memberQueryMemberInfoByIDAPorName,
  479. configShowRequirementVersionEnum,
  480. projectListProject,
  481. getFilterList,
  482. configShowTaskStatusEnum,
  483. createFilter,
  484. filterGetFilter,
  485. getChartListData,
  486. getChartData,
  487. updateStatus
  488. } from '@/api/taskIndex' // ajax
  489. import filterModal from '@/components/filterModal'
  490. import { settingQueryBizModuleList } from '@/api/defectManage'
  491. import openDialog from '@/views/projectManage/dialog_vue'
  492. // 过滤器
  493. import filterList from '@/views/projectManage/components/filterList'
  494. import normalDialog from '@/components/dialog/normalDialog'
  495. import mainTitle from '@/components/mainTitle'
  496. import chartView from '@/components/chartView'
  497. import chartSearchFormData from './renderData/chartSearchForm'
  498. import chartSearchForm from '@/components/searchHeader/searchForm'
  499. import '@/views/projectManage/publicCss/index.css'
  500. export default {
  501. components: {
  502. openDialog,
  503. filterList,
  504. normalDialog,
  505. mainTitle,
  506. chartView,
  507. filterModal,
  508. chartSearchForm
  509. },
  510. data() {
  511. return {
  512. size: 'small',
  513. pickerOptions: {
  514. shortcuts: [
  515. {
  516. text: '最近一周',
  517. onClick(picker) {
  518. const end = new Date()
  519. const start = new Date()
  520. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
  521. picker.$emit('pick', [start, end])
  522. }
  523. },
  524. {
  525. text: '最近一个月',
  526. onClick(picker) {
  527. const end = new Date()
  528. const start = new Date()
  529. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
  530. picker.$emit('pick', [start, end])
  531. }
  532. },
  533. {
  534. text: '最近三个月',
  535. onClick(picker) {
  536. const end = new Date()
  537. const start = new Date()
  538. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
  539. picker.$emit('pick', [start, end])
  540. }
  541. }
  542. ]
  543. },
  544. header_show: true,
  545. props: {
  546. value: 'id',
  547. label: 'moduleName',
  548. children: 'childModules',
  549. multiple: true
  550. },
  551. isFromDpmList: [
  552. { value: true, label: '是' },
  553. { value: false, label: '否' }
  554. ],
  555. isNoTest: [
  556. { value: 1, label: '是' },
  557. { value: 0, label: '否' }
  558. ],
  559. priorityColors: [
  560. '#F56C6C',
  561. '#FF8952',
  562. '#F5E300',
  563. '#7ED321',
  564. '#61D3B8',
  565. '#69B3FF',
  566. '#BDBDBD'
  567. ],
  568. arr_priority: [
  569. { value: 0, label: 'P0' },
  570. { value: 1, label: 'P1' },
  571. { value: 2, label: 'P2' },
  572. { value: 3, label: 'P3' }
  573. ],
  574. dialog_open: false,
  575. curIndex: 1,
  576. pageSize: 15,
  577. goodName: '更多筛选',
  578. options: [],
  579. daStatus: [], // 任务状态筛选option
  580. healthStage: [],
  581. list: [],
  582. userInformation: localStorage.getItem('username'),
  583. userNames: localStorage.getItem('realname'),
  584. form_task: {
  585. viewType: '0'
  586. },
  587. noTest: [], // 是否免测
  588. BusinessLine: [], // 业务线
  589. appClient: [], // 涉及业务线
  590. arr_platform: [], // 平台数据
  591. business_platform_Modular: [], // 模块数据
  592. arr_taskName: [], // 任务名称数据
  593. projectList: [], // 归属项目数据
  594. demandList: [], // 需求list
  595. dialogFormVisible: false,
  596. currentPage: 0,
  597. DetailedScreening: false,
  598. total: 0,
  599. biz: '',
  600. isToOne: true,
  601. loading: false,
  602. table_loading: false,
  603. test: {},
  604. task_table: [],
  605. form: {},
  606. arry: [],
  607. filterList: [],
  608. showEditSearch: false, // 显示管理过滤器
  609. searchForm: { name: null }, // 筛选项obj
  610. searchFormRules: {
  611. name: [
  612. { required: true, message: '请输入筛选项名称', trigger: 'blur' },
  613. { min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur' }
  614. ]
  615. },
  616. showSaveSearch: false, // 显示保存筛选项对话框
  617. nowTab: 'list',
  618. chartData: {},
  619. typeOptionList: [
  620. { value: '0', label: '任务状态' },
  621. { value: '1', label: '任务等级' },
  622. { value: '2', label: '开发负责人' },
  623. { value: '3', label: '测试负责人' },
  624. { value: '4', label: '跟版客户端' },
  625. { value: '5', label: '直接归属' }
  626. ],
  627. showChartModal: false,
  628. tableTitle: '',
  629. chartSearchFormRenderData: _.cloneDeep(chartSearchFormData)
  630. }
  631. },
  632. computed: {
  633. ...mapGetters(['bizId'])
  634. },
  635. watch: {
  636. bizId() {
  637. this.get_taskList()
  638. this.get_taskSelect()
  639. this.getFilterList() // 筛选项保存
  640. }
  641. },
  642. created() {
  643. this.get_taskList()
  644. this.get_taskSelect()
  645. this.bugDataGet()
  646. this.$store.state.data.status = true
  647. },
  648. mounted() {
  649. this.$nextTick(() => {
  650. this.bugDataGet()
  651. this.getFilterList() // 筛选项保存
  652. })
  653. this.updateChartSlectOption('isFromDpm', this.isFromDpmList)
  654. this.updateChartSlectOption('priority', this.arr_priority)
  655. },
  656. destroyed() {
  657. this.$store.state.data.status = false
  658. },
  659. methods: {
  660. filterModalConfirm() {
  661. this.showChartModal = false
  662. this.get_charts()
  663. },
  664. logHandle(d) {
  665. window.log({ c: 'task', d })
  666. },
  667. changeTab(e) {
  668. this.nowTab = e
  669. if (this.nowTab === 'charts') {
  670. this.get_charts()
  671. this.logHandle('changtab_task_charts')
  672. } else {
  673. this.chartData = {}
  674. this.get_taskList()
  675. }
  676. },
  677. async statusChange(e, id) {
  678. const res = await updateStatus({ status: e, id })
  679. if (res.code === 200) {
  680. this.get_charts()
  681. }
  682. },
  683. get_charts() {
  684. this.logHandle('get_task_charts')
  685. this.updateChartSearchFormValue()
  686. this.form_taskHandle()
  687. this.get_chartList()
  688. },
  689. async get_chartList() {
  690. this.table_loading = true
  691. // const res = await getChartData(this.form_task)
  692. getChartData(this.form_task).then(res => {
  693. this.chartData = res.data
  694. this.get_chartListDetial(res.data.data[0].code)
  695. }).catch(() => {
  696. this.table_loading = false
  697. })
  698. },
  699. async get_chartListDetial(code) {
  700. this.showChartModal = false
  701. if (code) {
  702. this.form_task.curIndex = 1
  703. this.form_task.code = code
  704. }
  705. const dataList = await getChartListData(this.form_task)
  706. this.task_table = dataList.data.list
  707. this.total = dataList.total
  708. this.tableTitle = dataList.data.title
  709. this.table_loading = false
  710. this.logHandle('get_task_charts_list_detial')
  711. },
  712. test2(item, e) {
  713. // 获取团队人员信息
  714. if (typeof this.test[item.idap] === 'undefined') {
  715. item.role = e
  716. this.test[item.idap] = item
  717. }
  718. return item.idap
  719. },
  720. // 保存筛选项
  721. saveSearch(formName) {
  722. // 保存筛选项
  723. this.$refs[formName].validate((valid) => {
  724. if (valid) {
  725. this.stratAndEnd = this.stratAndEnd ? this.stratAndEnd : []
  726. this.form_task.createStartTime = this.stratAndEnd[0] || null
  727. this.form_task.createEndTime = this.stratAndEnd[1] || null
  728. const isExistName = this.filterList.some((item) => {
  729. return item.name === this.searchForm.name
  730. })
  731. if (isExistName) {
  732. this.$message({
  733. showClose: true,
  734. message: '筛选项名称重名',
  735. type: 'error'
  736. })
  737. } else {
  738. this.toSave()
  739. }
  740. } else {
  741. this.$message({
  742. showClose: true,
  743. message: '筛选项名称不能为空',
  744. type: 'error'
  745. })
  746. return false
  747. }
  748. })
  749. },
  750. // 保存过滤器
  751. async toSave() {
  752. const saveObj = _.cloneDeep(this.form_task)
  753. delete saveObj.curIndex
  754. delete saveObj.pageSize
  755. const res = await createFilter({
  756. name: this.searchForm.name,
  757. content: JSON.stringify(saveObj),
  758. bizId: this.bizId,
  759. filterType: 2
  760. })
  761. if (res.code === 200) {
  762. this.$message({ showClose: true, message: '保存成功', type: 'success' })
  763. this.showSaveSearch = false
  764. this.getFilterList()
  765. this.searchForm.name = null
  766. }
  767. },
  768. async getFilterList() {
  769. // 获取过滤器列表
  770. const params = {
  771. bizId: this.bizId,
  772. filterType: 2
  773. }
  774. const res = await getFilterList(params)
  775. this.filterList = res.data
  776. },
  777. deleteFilter() {
  778. this.$router.push({ path: this.$route.path })
  779. this.getFilterList()
  780. },
  781. form_taskHandle() {
  782. if (this.bizId === -1) return
  783. // 查询
  784. if (this.isToOne) {
  785. this.curIndex = 1
  786. this.currentPage = 1
  787. }
  788. // this.table_loading = true
  789. this.form_task.bizId = this.bizId
  790. this.form_task.pageSize = this.pageSize
  791. this.form_task.curIndex = this.curIndex
  792. for (const key in this.form_task) {
  793. // 接口不接受空值的处理
  794. if (this.form_task[key] === '') {
  795. delete this.form_task[key]
  796. }
  797. }
  798. if (this.form_task.date) {
  799. this.form_task.createTimeBegin = this.form_task.date[0]
  800. this.form_task.createTimeEnd = this.form_task.date[1]
  801. } else {
  802. delete this.form_task.createTimeBegin
  803. delete this.form_task.createTimeEnd
  804. }
  805. },
  806. get_taskList(e) {
  807. this.form_taskHandle()
  808. taskList(this.form_task).then((res) => {
  809. this.task_table = res.data
  810. this.total = res.total
  811. this.table_loading = false
  812. this.logHandle('get_task')
  813. })
  814. configShowRequirementVersionEnum({ bizId: this.bizId }).then((res) => {
  815. // 获取需求(查询)
  816. const demandList = res.data.map((t) => ({
  817. ...t,
  818. label: t.name,
  819. value: t.id
  820. }))
  821. this.demandList = demandList
  822. this.updateChartSlectOption('requireId', demandList)
  823. })
  824. this.isToOne = true
  825. },
  826. async remoteMethod(query) {
  827. // 人员查询
  828. if (query !== '') {
  829. this.loading = true
  830. const res = await memberQueryMemberInfoByIDAPorName({
  831. memberIDAP: query
  832. })
  833. const obj = {}
  834. this.options = res.data.reduce((cur, next) => {
  835. obj[next.idap] ? '' : (obj[next.idap] = true && cur.push(next))
  836. return cur
  837. }, [])
  838. this.loading = false
  839. } else {
  840. this.options = []
  841. }
  842. this.updateChartSlectOption('PersonInCharge', this.options)
  843. this.updateChartSlectOption('creater', this.options)
  844. },
  845. showSelect() {
  846. this.DetailedScreening = !this.DetailedScreening
  847. this.goodName === '更多筛选'
  848. ? (this.goodName = '收起筛选')
  849. : (this.goodName = '更多筛选')
  850. },
  851. team_dates(e) {
  852. // 改变成员
  853. this.form.arry = []
  854. for (const i in e) {
  855. this.form.arry.push(this.test[e[i]])
  856. }
  857. this.arry = this.form.arry.map((item) => {
  858. return { memberIDAP: item.idap, department: item.deptid, role: 0 }
  859. })
  860. },
  861. open_created() {
  862. // 打开弹窗
  863. this.dialog_open = true
  864. this.$nextTick(() => {
  865. this.$refs.task_createdUpdata.init(1)
  866. })
  867. },
  868. link_task(id) {
  869. const bizId_id = EncryptId(`${this.bizId}_${id}`)
  870. if (localStorage.getItem('openPageHandle') === 'self') {
  871. this.$router.push({ name: '任务详情', query: { bizId_id: bizId_id }})
  872. } else {
  873. const newTab = this.$router.resolve({
  874. name: '任务详情',
  875. query: { bizId_id: bizId_id }
  876. })
  877. window.open(newTab.href, '_blank')
  878. }
  879. },
  880. query_Reset() {
  881. // 重置
  882. this.form_task = {
  883. ...this.form_task,
  884. notest: '',
  885. bizId: '',
  886. status: '',
  887. stage: '',
  888. id: '',
  889. projectId: '',
  890. requireId: '',
  891. PersonInCharge: '',
  892. Participant: '',
  893. creater: '',
  894. isFromDpm: '',
  895. priority: '',
  896. date: []
  897. }
  898. if (this.nowTab === 'charts') {
  899. this.form_task = { ...this.form_task, name: '', statusList: [] }
  900. }
  901. this.updateChartSearchFormValue()
  902. if (this.nowTab === 'charts') {
  903. this.get_charts()
  904. } else {
  905. this.get_taskList()
  906. }
  907. },
  908. handleSizeChange(size) {
  909. // 分页
  910. this.pageSize = size
  911. this.isToOne = false
  912. this.form_taskHandle()
  913. if (this.nowTab === 'charts') {
  914. this.get_chartListDetial()
  915. return
  916. }
  917. this.get_taskList(1)
  918. },
  919. handleCurrentChange(curIndex) {
  920. // 分页
  921. this.curIndex = curIndex
  922. this.currentPage = curIndex
  923. this.isToOne = false
  924. this.form_taskHandle()
  925. if (this.nowTab === 'charts') {
  926. this.get_chartListDetial()
  927. return
  928. }
  929. this.get_taskList()
  930. },
  931. async get_taskSelect() {
  932. if (this.bizId === -1) return
  933. // 下拉菜单数据
  934. const res = await configShowTaskEnum()
  935. if (res.code === 200) {
  936. const healthStage = res.data.taskStage.map((t) => ({
  937. ...t,
  938. label: t.msg,
  939. value: t.code
  940. }))
  941. this.healthStage = healthStage
  942. this.updateChartSlectOption('stage', healthStage)
  943. this.noTest = res.data.noTest // 是否免测
  944. this.taskSource = res.data.taskSource // 归属需求
  945. this.appClient = res.data.appClient // 涉及客户端
  946. }
  947. const res1 = await configShowTaskStatusEnum(this.bizId)
  948. if (res1.code === 200) {
  949. const daStatus = res1.data.taskStatus.map((t) => ({
  950. ...t,
  951. label: t.msg,
  952. value: t.code
  953. }))
  954. this.daStatus = daStatus
  955. this.updateChartSlectOption('statusList', daStatus)
  956. }
  957. const res2 = await projectListProject({ bizId: this.bizId })
  958. if (res2.code === 200) {
  959. const projectList = res2.data.map((t) => ({
  960. ...t,
  961. label: t.name,
  962. value: t.id
  963. }))
  964. this.projectList = projectList
  965. this.updateChartSlectOption('projectId', projectList)
  966. }
  967. },
  968. bugDataGet() {
  969. // 所属模块
  970. this.biz = this.bizId
  971. if (this.bizId === -1) {
  972. this.biz = this.$store.state.global.bizId
  973. }
  974. settingQueryBizModuleList(this.biz).then((res) => {
  975. this.business_platform_Modular = this.getRequireData(res.data)
  976. })
  977. },
  978. getRequireData(data) {
  979. for (let i = 0; i < data.length; i++) {
  980. data[i].childModules && data[i].childModules.length < 1
  981. ? delete data[i].childModules
  982. : this.getRequireData(data[i].childModules)
  983. }
  984. return data
  985. },
  986. async getFilterItem(filterId) {
  987. // 获取单个过滤器
  988. const res = await filterGetFilter(filterId)
  989. if (res.code === 200) {
  990. const filter = JSON.parse(res.data.content)
  991. Object.assign(this.form_task, filter)
  992. this.curIndex = 1
  993. this.get_taskList()
  994. }
  995. },
  996. chartSearchFormChange(key, value) {
  997. this.form_task[key] = value
  998. },
  999. updateChartSlectOption(key, option) {
  1000. this.chartSearchFormRenderData.map((t) => {
  1001. if (t.key === key) {
  1002. t.option = option
  1003. }
  1004. })
  1005. },
  1006. updateChartSearchFormValue() {
  1007. this.chartSearchFormRenderData.map((t) => {
  1008. t.value = this.form_task[t.key]
  1009. })
  1010. }
  1011. }
  1012. }
  1013. </script>
  1014. <style lang="less" scoped>
  1015. .chartView {
  1016. .chartSearchTitle {
  1017. width: 50px;
  1018. color: #333333;
  1019. font-size: 14px;
  1020. }
  1021. .screen {
  1022. margin-left: 20px;
  1023. }
  1024. }
  1025. .stylus-head {
  1026. position: relative;
  1027. }
  1028. .new-tab-open {
  1029. position: absolute;
  1030. left: 120px;
  1031. }
  1032. .filter {
  1033. display: flex;
  1034. justify-content: space-between;
  1035. align-items: baseline;
  1036. margin-top: 15px;
  1037. .filterWrap {
  1038. display: flex;
  1039. align-items: baseline;
  1040. .title {
  1041. width: 100px;
  1042. }
  1043. .itemBox {
  1044. .itemFilter {
  1045. display: inline-block;
  1046. margin-right: 20px;
  1047. margin-bottom: 10px;
  1048. cursor: pointer;
  1049. }
  1050. }
  1051. }
  1052. .btn {
  1053. font-size: 14px;
  1054. color: #00a0ff;
  1055. cursor: pointer;
  1056. min-width: 80px;
  1057. text-align: center;
  1058. }
  1059. }
  1060. .subtitle {
  1061. color: #333;
  1062. font-size: 16px;
  1063. background: #fff;
  1064. font-weight: 700;
  1065. padding: 16px 12px;
  1066. }
  1067. .search_box {
  1068. .item {
  1069. // width: 270px;
  1070. margin-right: 15px;
  1071. .queryName {
  1072. min-width: 80px;
  1073. }
  1074. }
  1075. }
  1076. </style>
  1077. <style>
  1078. .el-loading-mask {
  1079. z-index: 8;
  1080. }
  1081. .requirement-xx .el-table .cell {
  1082. padding: 5px 0;
  1083. font-size: 14px;
  1084. font-family: MicrosoftYaHei;
  1085. }
  1086. .requirement-xx .el-table .el-table__body tr:hover td {
  1087. color: #409eff;
  1088. background: #edf6ff;
  1089. } /*hover时字体, 背景颜色*/
  1090. .footer {
  1091. text-align: right;
  1092. margin: 1%;
  1093. background-color: #ffffff;
  1094. border-radius: 4px;
  1095. }
  1096. .bgborder .el-table .cell {
  1097. box-sizing: border-box;
  1098. overflow: hidden;
  1099. text-overflow: ellipsis;
  1100. word-break: break-all;
  1101. line-height: 23px;
  1102. padding-right: 10px;
  1103. margin: -6px 0 -2px 0 !important;
  1104. }
  1105. .el-table .warning-row {
  1106. background: oldlace;
  1107. }
  1108. .drop_down {
  1109. font-size: 14px;
  1110. color: #333333;
  1111. }
  1112. .requirement_el-dropdown-menu {
  1113. max-height: 300px !important;
  1114. max-width: 200px;
  1115. overflow: auto !important;
  1116. }
  1117. .el-dropdown-menu__item:not(.is-disabled):hover {
  1118. background-color: #f6f7fa;
  1119. color: #606266;
  1120. }
  1121. .div_priority {
  1122. display: inline-block;
  1123. width: 38px;
  1124. text-align: center;
  1125. line-height: 24px;
  1126. font-size: 14px;
  1127. color: #fff;
  1128. border-radius: 4px;
  1129. margin-right: 30px;
  1130. }
  1131. .tagNotification {
  1132. background: rgba(255, 137, 82, 15%);
  1133. color: #ff8952;
  1134. padding: 0 5px;
  1135. border-radius: 8px;
  1136. margin-left: 10px;
  1137. }
  1138. .tagNotification1 {
  1139. background: rgba(245, 108, 108, 17%);
  1140. color: #f56c6c;
  1141. padding: 0 5px;
  1142. border-radius: 8px;
  1143. margin-left: 10px;
  1144. }
  1145. </style>
  1146. <style lang="less" scoped>
  1147. .stylus-head /deep/ .el-form-item__label {
  1148. color: #333333;
  1149. font-weight: 400;
  1150. }
  1151. .stylus-content /deep/ .el-table .el-table__body tr:hover td {
  1152. // color #409EFF !important
  1153. background: #EDF6FF;
  1154. }
  1155. .stylus-head /deep/ .el-divider--horizontal {
  1156. margin: 10px 0;
  1157. }
  1158. .stylus-head /deep/ .el-form-item {
  1159. margin-bottom: 0;
  1160. }
  1161. .stylus-head {
  1162. width: 100%;
  1163. padding: 15px;
  1164. margin-bottom: 10px;
  1165. background-color: white;
  1166. border-radius: 4px;
  1167. .stylus-title {
  1168. display: flex;
  1169. justify-content: space-between;
  1170. align-items: center;
  1171. }
  1172. .stylus-more {
  1173. background: rgba(252, 252, 252, 1);
  1174. border-radius: 4px;
  1175. padding: 15px;
  1176. min-height: 100px;
  1177. margin-top: 22px;
  1178. border: 1px solid rgba(238, 238, 238, 1);
  1179. width: 100%;
  1180. }
  1181. }
  1182. .stylus-content {
  1183. width: 100%;
  1184. padding: 0.3% 1% 1% 1%;
  1185. margin: 0 auto;
  1186. background-color: white;
  1187. border-radius: 4px;
  1188. // min-height: calc(100vh - 143px);
  1189. .stylus-hover:hover {
  1190. color: #409EFF !important;
  1191. cursor: pointer;
  1192. }
  1193. }
  1194. </style>