Browse Source

工作项

master
陈裕财 4 years ago
parent
commit
ba6fee0f21
  1. 69
      src/common/js/treeTool.js
  2. 227
      src/views/xm/core/xmMenu/XmMenuEdit.vue
  3. 52
      src/views/xm/core/xmMenu/XmMenuMng.vue
  4. 375
      src/views/xm/core/xmWorkItem/XmSubBugList.vue
  5. 134
      src/views/xm/core/xmWorkItem/XmSubMenuList.vue
  6. 129
      src/views/xm/core/xmWorkItem/XmSubTaskList.vue
  7. 207
      src/views/xm/core/xmWorkItem/XmSubWorkItem.vue

69
src/common/js/treeTool.js

@ -1,21 +1,22 @@
export default {
reloadAllChildren: function(table,maps, rows,parentIdName,loadChildren,idMaps) {
reloadAllChildren: function(table,maps, rows,parentIdName,loadChildren,idMaps) {
debugger;
if(!rows||rows.length==0){
return;
}
if(!maps || maps.length==0){
return;
}
if(!table){
return;
}
var lazyTreeNodeMap=table.store.states.lazyTreeNodeMap
var parentIds=rows.map(i=>i[parentIdName])
var parentIds=rows.map(i=>i[parentIdName])
if(idMaps==null){
idMaps=new Map();
}
@ -26,47 +27,47 @@ export default {
if(!idMaps.has(k)){
idMaps.set(k,k);
if (maps.get(k)) {
const { tree, treeNode, resolve } = maps.get(k)
const { tree, treeNode, resolve } = maps.get(k)
lazyTreeNodeMap[k]=[]
if (tree) { // 重新执行父节点加载子级操作
loadChildren(tree, treeNode, resolve)
if(tree[parentIdName]){
if(tree[parentIdName]){
this.reloadAllChildren(table,maps, [tree],parentIdName,loadChildren,idMaps)
}
}
}
}
});
}
}
});
},
reloadChildren: function(table,maps, parentId,parentIdName,loadChildren) {
reloadChildren: function(table,maps, parentId,parentIdName,loadChildren) {
var params={};
params[parentIdName]=parentId;
this.reloadAllChildren(table,maps, [params],parentIdName,loadChildren)
},
reloadChildrenByOpType: function(table,maps, parentId,parentIdName,loadChildren,opType) {
this.reloadAllChildren(table,maps, [params],parentIdName,loadChildren)
},
reloadChildrenByOpType: function(table,maps, parentId,parentIdName,loadChildren,opType) {
var lazyTreeNodeMap=table.store.states.lazyTreeNodeMap
if (maps.get(parentId)) {
const { tree, treeNode, resolve } = maps.get(parentId)
const { tree, treeNode, resolve } = maps.get(parentId)
if (tree) { // 重新执行父节点加载子级操作
var oldDatas=lazyTreeNodeMap[parentId]
loadChildren(tree, treeNode, resolve,oldDatas,opType)
loadChildren(tree, treeNode, resolve,oldDatas,opType)
}
}
},
clearOpType: function(table,maps,parentId,parentIdName,loadChildren) {
}
},
clearOpType: function(table,maps,parentId,parentIdName,loadChildren) {
var lazyTreeNodeMap=table.store.states.lazyTreeNodeMap
if (maps.get(parentId)) {
const { tree, treeNode, resolve } = maps.get(parentId)
const { tree, treeNode, resolve } = maps.get(parentId)
if (tree) { // 重新执行父节点加载子级操作
var oldDatas=lazyTreeNodeMap[parentId]
loadChildren(tree, treeNode, resolve,oldDatas,"clearOpType")
loadChildren(tree, treeNode, resolve,oldDatas,"clearOpType")
}
}
},
}
},
/**
* 将类表数据转换为如下树状结构的数据
* {
@ -81,12 +82,12 @@ export default {
* @param {*} pidName 上级字段名称 pmenId
* @param {*} idName 本条数据主键字段名称 menuId
* @param {*} rowCallBack(data),如果需要对部分字段进行转换可以传入这个回调函数比如需要将 name:'陈天财' => label:'陈天财'
* @returns
* @returns
*/
translateDataToTree: function(data2,pidName,idName,rowCallBack) {
translateDataToTree: function(data2,pidName,idName,rowCallBack) {
var data=JSON.parse(JSON.stringify(data2));
let parents = data.filter(value =>{
//如果我的上级为空,则我是最上级
//如果我的上级为空,则我是最上级
if(value[pidName] == 'undefined' || value[pidName] == null || value[pidName] == ''|| value[pidName] == '0'){
return true;
@ -96,15 +97,15 @@ export default {
}else {
return true
}
})
})
let children = data.filter(value =>{
if(data.some(i=>value[pidName]==i[idName])){
return true;
}else{
return false;
}
})
}
})
let translator = (parents, children) => {
parents.forEach((parent) => {
if(rowCallBack){
@ -127,6 +128,6 @@ export default {
translator(parents, children)
return parents
},
},
}

227
src/views/xm/core/xmMenu/XmMenuEdit.vue

@ -1,27 +1,27 @@
<template>
<section>
<el-row class="page-main ">
<el-form :model="editForm" label-width="100px" label-position="left" :rules="editFormRules" ref="editForm">
<el-row :gutter="10">
<el-form :model="editForm" label-width="100px" label-position="left" :rules="editFormRules" ref="editForm">
<el-row :gutter="10">
<el-col :span="6">
<el-form-item label="序号名称" prop="seqNo" >
<el-form-item label="序号名称" prop="seqNo" >
<template slot="label">
<div class="icon" :style="{backgroundColor: calcMenuLabel.color }">
<i :class="calcMenuLabel.icon"></i>
</div>
</div>
{{calcMenuLabel.label}}
</template>
<el-input v-model="editForm.seqNo" title="序号 如 1.1,1.2.3,1.3.2等" style="width:100%;" placeholder="如1.0 , 1.1 , 1.1.1等" @change="editXmMenuSomeFields(editForm,'seqNo',$event)"></el-input>
</el-form-item>
</template>
<el-input v-model="editForm.seqNo" title="序号 如 1.1,1.2.3,1.3.2等" style="width:100%;" placeholder="如1.0 , 1.1 , 1.1.1等" @change="editXmMenuSomeFields(editForm,'seqNo',$event)"></el-input>
</el-form-item>
</el-col>
<el-col :span="18">
<el-form-item label="" prop="menuName" label-width="0px">
<el-input v-model="editForm.menuName" placeholder="名称" title="名称" @change="editXmMenuSomeFields(editForm,'menuName',$event)"></el-input>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10">
<el-row :gutter="10">
<el-col :span="8">
<el-form-item label="归属产品" prop="productId">
<font v-if="editForm.productId">{{editForm.productName?editForm.productName:editForm.productId}}</font>
@ -30,168 +30,168 @@
<el-col :span="8">
<el-form-item v-if="!editForm.pmenuId" :label="editForm.dclass==='3'?'归属特性':(editForm.dclass==='2'?'归属史诗':'归属')" prop="pmenuId">
</el-form-item>
<el-form-item v-else :label="editForm.dclass==='3'?'归属特性':(editForm.dclass==='2'?'归属史诗':'归属')" prop="pmenuId">
</el-form-item>
<el-form-item v-else :label="editForm.dclass==='3'?'归属特性':(editForm.dclass==='2'?'归属史诗':'归属')" prop="pmenuId">
<div v-if="editForm.dclass==='2'" class="icon" style="background-color: rgb(255, 153, 51);">
<i class="el-icon-s-promotion"></i>
</div>
</div>
<div v-if="editForm.dclass==='3'" class="icon" style="background-color: rgb(0, 153, 51);">
<i class="el-icon-s-flag"></i>
</div>
{{editForm.pmenuName?editForm.pmenuName:editForm.pmenuId}}
</el-form-item>
</el-col>
</div>
{{editForm.pmenuName?editForm.pmenuName:editForm.pmenuId}}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="负责人" prop="mmUserid">
<el-tag type="text" v-if="editForm.mmUserid" closable @close="clearMmUser">{{editForm.mmUsername}}</el-tag>
<el-tag type="text" v-if="editForm.mmUserid" closable @close="clearMmUser">{{editForm.mmUsername}}</el-tag>
<el-button type="text" @click="mmUserSelectVisible=true">选跟进人</el-button>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
</el-row>
<el-row :gutter="10">
<el-col :span="8">
<el-form-item label="需求状态" prop="status">
<el-form-item label="需求状态" prop="status">
<el-select style="display:block;width:100px;" v-model="editForm.status" @change="editXmMenuSomeFields(editForm,'status',$event)">
<el-option v-for="i in this.dicts.menuStatus" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</el-select>
</el-form-item>
</el-col>
</el-col>
<el-col :span="8">
<el-form-item label="进度" prop="finishRate">
<el-progress :percentage="editForm.finishRate"></el-progress>
<el-form-item label="进度" prop="finishRate">
<el-progress :percentage="editForm.finishRate?editForm.finishRate:0"></el-progress>
</el-form-item>
</el-col>
</el-col>
<el-col :span="8">
<el-form-item label="截止时间" prop="startTime" >
<el-form-item label="截止时间" prop="startTime" >
<el-date-picker type="daterange" style="width:220px;" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd" v-model="dateRanger" @change="editXmMenuSomeFields(editForm,'startTime',dateRanger)"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
<el-tabs value="1" >
<el-tab-pane label="基本信息'" name="1" >
<el-row>
<el-col :span="12">
<el-form-item label="提出人" prop="proposerId">
<el-tag type="text" v-if="editForm.proposerId" closable @close="clearProposer">{{editForm.proposerName}}</el-tag>
<el-tag type="text" v-if="editForm.proposerId" closable @close="clearProposer">{{editForm.proposerName}}</el-tag>
<el-button type="text" @click="selectProposer">选提出人</el-button>
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提出时间" prop="ctime" >
<el-date-picker value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd" v-model="editForm.ctime" @change="editXmMenuSomeFields(editForm,'ctime',$event)"></el-date-picker>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-row>
<el-col :span="12">
<el-form-item label="需求类型" prop="dtype" >
<el-form-item label="需求类型" prop="dtype" >
<el-select v-model="editForm.dtype" @change="editXmMenuSomeFields(editForm,'dtype',$event)">
<el-option v-for="i in this.dicts.demandType" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</el-form-item>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求来源" prop="source">
<el-form-item label="需求来源" prop="source">
<el-select v-model="editForm.source" @change="editXmMenuSomeFields(editForm,'source',$event)">
<el-option v-for="i in this.dicts.demandSource" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求层次" prop="dlvl" >
<el-form-item label="需求层次" prop="dlvl" >
<el-select v-model="editForm.dlvl" @change="editXmMenuSomeFields(editForm,'dlvl',$event)">
<el-option v-for="i in this.dicts.demandLvl" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</el-form-item>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="优先级" prop="priority" >
<el-form-item label="优先级" prop="priority" >
<el-select v-model="editForm.priority" @change="editXmMenuSomeFields(editForm,'priority',$event)">
<el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</el-form-item>
<el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="概述" name="4">
</el-tab-pane>
<el-tab-pane label="概述" name="4">
<el-form-item label="需求概述" prop="remark">
<el-input type="textarea" :autosize="{ minRows: 6, maxRows: 20}" v-model="editForm.remark" placeholder="什么人?做什么事?,为什么?如: 作为招聘专员,我需要统计员工半年在职/离职人数,以便我能够制定招聘计划" ></el-input>
</el-form-item>
</el-form-item>
<el-row class="padding">
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'remark',editForm.remark)" :disabled="load.edit==true">提交</el-button>
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'remark',editForm.remark)" :disabled="load.edit==true">提交</el-button>
</el-row>
</el-tab-pane>
<el-tab-pane :label="'子工作项'+(subWorkItemNum>=0?'('+subWorkItemNum+')':'')" name="6">
<xm-sub-work-item :parent-xm-menu="editForm" @sub-work-item-num="setSubWorkItemNum"></xm-sub-work-item>
</el-tab-pane>
</el-tab-pane>
<el-tab-pane :label="'子工作项'+(subWorkItemNum>=0?'('+subWorkItemNum+')':'')" name="6">
<xm-sub-work-item :parent-xm-menu="editForm" @sub-work-item-num="setSubWorkItemNum" @add-sub-menu="onAddSubMenu"></xm-sub-work-item>
</el-tab-pane>
<el-tab-pane :label="'工时('+editForm.mactWorkload+' h)'" name="2">
<el-form-item label="数据收集方式" prop="calcType">
<el-form-item label="数据收集方式" prop="calcType">
<el-radio v-model="editForm.calcType" label="3" placeholder="下级往上级汇总" :disabled="editForm.ntype==='0'">下级往上级汇总</el-radio>
<el-radio v-model="editForm.calcType" label="1" placeholder="由任务汇总" :disabled="editForm.ntype==='1'">由任务汇总</el-radio>
<el-radio v-model="editForm.calcType" label="1" placeholder="由任务汇总" :disabled="editForm.ntype==='1'">由任务汇总</el-radio>
<el-radio v-model="editForm.calcType" label="2" placeholder="手工填报" :disabled="editForm.ntype==='1'">手工填报</el-radio>
</el-form-item>
</el-form-item>
<el-form-item label="工时进度" prop="mactRate" >
<el-progress style="width:60%;" :text-inside="true" :stroke-width="15" :percentage="editForm.mactRate?editForm.mactRate:0"></el-progress>
</el-form-item>
</el-form-item>
<el-form-item label="预估工期" prop="budgetHours">
<el-input-number :disabled="editForm.calcType!=='2' " style="width:200px;" v-model="editForm.budgetHours" :precision="2" :step="8" :min="0" placeholder="预计工期(小时)"></el-input-number> &nbsp;h
</el-form-item>
</el-form-item>
<el-form-item label="预估工时" prop="budgetWorkload">
<el-input-number :disabled="editForm.calcType!=='2' " style="width:200px;" v-model="editForm.budgetWorkload" :precision="2" :step="8" :min="0" placeholder="预计工时(小时)"></el-input-number> &nbsp;h
</el-form-item>
</el-form-item>
<el-form-item label="实际工时" prop="mactWorkload">
<el-input-number :disabled="editForm.calcType!=='2' " style="width:200px;" v-model="editForm.mactWorkload" :precision="2" :step="8" :min="0" placeholder="实际工时(小时)"></el-input-number> &nbsp;h
</el-form-item>
</el-form-item>
<font color="blue" style="font-size:10px;">控制规则:
<br>下级往上汇总指工时数据按 &nbsp;用户故事->特性->史诗 &nbsp;这样的汇总关系将数据逐级往上汇总
<br>由任务汇总 指用户故事的工时数据由任务汇总
<br>手工填报 指用户故事的工时数据来自手工填报无论是否关联了任务都不从任务汇总
</font>
<el-row class="padding">
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'workload',{mactWorkload:editForm.mactWorkload,budgetWorkload:editForm.budgetWorkload,mactRate:editForm.mactRate,budgetHours:editForm.budgetHours})" :disabled="load.edit==true">提交</el-button>
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'workload',{mactWorkload:editForm.mactWorkload,budgetWorkload:editForm.budgetWorkload,mactRate:editForm.mactRate,budgetHours:editForm.budgetHours})" :disabled="load.edit==true">提交</el-button>
</el-row>
</el-tab-pane>
<el-tab-pane label="成本" name="3">
<el-tab-pane label="成本" name="3">
<el-form-item label="预估金额" prop="budgetAmount">
<el-input-number :disabled="editForm.calcType!=='2' " style="width:200px;" v-model="editForm.budgetAmount" :precision="2" :step="100" :min="0" placeholder="预算金额"></el-input-number>
</el-form-item>
<el-input-number :disabled="editForm.calcType!=='2' " style="width:200px;" v-model="editForm.budgetAmount" :precision="2" :step="100" :min="0" placeholder="预算金额"></el-input-number>
</el-form-item>
<el-form-item label="实际金额" prop="mactAmount">
<el-input-number :disabled="editForm.calcType!=='2' " style="width:200px;" v-model="editForm.mactAmount" :precision="2" :step="100" :min="0" placeholder="实际金额"></el-input-number>
</el-form-item>
<el-input-number :disabled="editForm.calcType!=='2' " style="width:200px;" v-model="editForm.mactAmount" :precision="2" :step="100" :min="0" placeholder="实际金额"></el-input-number>
</el-form-item>
<el-row class="padding">
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'budgetAmount',{budgetAmount:editForm.budgetAmount,mactAmount:editForm.mactAmount })" :disabled="load.edit==true">提交</el-button>
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'budgetAmount',{budgetAmount:editForm.budgetAmount,mactAmount:editForm.mactAmount })" :disabled="load.edit==true">提交</el-button>
</el-row>
</el-tab-pane>
<el-tab-pane label="链接" name="5">
<el-form-item label="需求链接" prop="demandUrl">
<el-input v-model="editForm.demandUrl" placeholder="需求链接" ></el-input>
</el-form-item>
<el-tab-pane label="链接" name="5">
<el-form-item label="需求链接" prop="demandUrl">
<el-input v-model="editForm.demandUrl" placeholder="需求链接" ></el-input>
</el-form-item>
<el-form-item label="代码链接" prop="codeUrl">
<el-input v-model="editForm.codeUrl" placeholder="代码链接" ></el-input>
</el-form-item>
<el-input v-model="editForm.codeUrl" placeholder="代码链接" ></el-input>
</el-form-item>
<el-form-item label="设计链接" prop="designUrl">
<el-input v-model="editForm.designUrl" placeholder="设计链接" ></el-input>
</el-form-item>
<el-input v-model="editForm.designUrl" placeholder="设计链接" ></el-input>
</el-form-item>
<el-form-item label="操作手册链接" prop="operDocUrl">
<el-input v-model="editForm.operDocUrl" placeholder="操作手册链接" ></el-input>
</el-form-item>
<el-input v-model="editForm.operDocUrl" placeholder="操作手册链接" ></el-input>
</el-form-item>
<el-row class="padding">
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'link',{demandUrl:editForm.demandUrl,codeUrl:editForm.codeUrl,designUrl:editForm.designUrl,operDocUrl:editForm.operDocUrl})" :disabled="load.edit==true">提交</el-button>
<el-button v-loading="load.edit" type="primary" @click.native="editXmMenuSomeFields(editForm,'link',{demandUrl:editForm.demandUrl,codeUrl:editForm.codeUrl,designUrl:editForm.designUrl,operDocUrl:editForm.operDocUrl})" :disabled="load.edit==true">提交</el-button>
</el-row>
</el-tab-pane>
<el-tab-pane label="wiki" name="7">
<el-tab-pane label="wiki" name="7">
关联知识库
</el-tab-pane>
<el-tab-pane label="附件" name="8">
<el-tab-pane label="附件" name="8">
上传附件
</el-tab-pane>
</el-tabs>
@ -199,18 +199,18 @@
<el-drawer title="选择提出人" :visible.sync="proposerSelectVisible" size="60%" append-to-body>
<users-select @confirm="onProposerSelected" ref="usersSelect"></users-select>
</el-drawer>
<el-drawer title="选择跟进人" :visible.sync="mmUserSelectVisible" size="60%" append-to-body>
<users-select @confirm="onMmUserSelected" ref="mmUsersSelect"></users-select>
</el-drawer>
</el-row>
<el-drawer append-to-body title="标签" :visible.sync="tagSelectVisible" class="dialog-body" size="60%">
<tag-mng :tagIds="editForm.tagIds?editForm.tagIds.split(','):[]" :jump="true" @select-confirm="onTagSelected">
</tag-mng>
</el-drawer>
</section>
</template>
@ -243,7 +243,7 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
}
}
},
calcMenuLabel(){
calcMenuLabel(){
var params={label:'工作项',icon:'',color:''};
if(this.editForm.dclass==='1'){
params={label:'史诗',icon:'el-icon-s-promotion',color:'rgb(255, 153, 51)'};
@ -251,9 +251,9 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
params={label:'特性',icon:'el-icon-s-flag',color:'rgb(0, 153, 51)'};
}else if(this.editForm.dclass==='3'){
params={label:'故事',icon:'el-icon-document',color:' rgb(79, 140, 255)'};
}
}
return params;
},
},
},
props:['xmMenu','visible','parentMenu','product','dclass'],
watch: {
@ -263,11 +263,11 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
'visible':function(visible) {
if(visible==true){
if(this.editForm.startTime && this.editForm.endTime){
this.dateRanger.push(this.editForm.startTime)
this.dateRanger.push(this.editForm.startTime)
this.dateRanger.push(this.editForm.endTime)
}
}
},
},
'editForm.mactWorkload':function(val,oldVal){
if(!this.editForm.budgetWorkload){
return;
@ -320,7 +320,7 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
mmUserSelectVisible:false,
dicts:{
menuStatus:[
{id:"0", name:"初始"},
{id:"1", name:"待评审"},
{id:"2", name:"待设计"},
@ -330,7 +330,7 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
{id:"6", name:"待上线"},
{id:"7", name:"运行中"},
{id:"8", name:"已下线"},
{id:"9", name:"已删除"},
{id:"9", name:"已删除"},
]
},
tagSelectVisible:false,
@ -350,7 +350,7 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
this.$emit('cancel');
},
//XmMenu @submit="afterAddSubmit"
editSubmit: function () {
editSubmit: function () {
this.$refs.editForm.validate((valid) => {
if (valid) {
@ -408,8 +408,8 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
this.editForm.status=status;
},
onTagSelected(tags) {
this.tagSelectVisible = false;
if(tags && tags.length>0){
this.tagSelectVisible = false;
if(tags && tags.length>0){
this.editForm.tagIds=tags.map(i=>i.tagId).join(",")
this.editForm.tagNames=tags.map(i=>i.tagName).join(",")
}else{
@ -455,13 +455,14 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
params[fieldName]=$event
}else{
params={...params,...$event}
}
}
}
editXmMenuSomeFields(params).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
Object.assign(row,params)
Object.assign(row,params)
this.$emit("edit-fields",params);
if(fieldName==='remark'||fieldName==='link'){
this.$notify({showClose:true,message:tips.msg,type:tips.isOk?'success':'error'})
}
@ -470,6 +471,10 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
}
})
},
onAddSubMenu(menu){
debugger;
this.$emit("add-sub-menu",menu)
}
},//end method
components: {
// 'xm-menu-edit':XmMenuEdit
@ -480,14 +485,14 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
XmSubWorkItem,
},
mounted() {
initSimpleDicts('all',['demandSource','demandLvl','demandType','priority','menuStatus'] ).then(res=>{
this.dicts=res.data.data;
})
this.editForm=Object.assign(this.editForm, this.xmMenu);
if(this.editForm.startTime && this.editForm.endTime){
this.dateRanger.push(this.editForm.startTime)
this.dateRanger.push(this.editForm.startTime)
this.dateRanger.push(this.editForm.endTime)
}
/**在下面写其它函数***/
@ -509,5 +514,5 @@ import XmMenuExchangeMng from '../xmMenuExchange/XmMenuExchangeMng.vue';
font-size: 14px;
display: inline-block;
margin-right: 5px;
}
}
</style>

52
src/views/xm/core/xmMenu/XmMenuMng.vue

@ -199,7 +199,7 @@
<el-tooltip v-if="scope.row.dclass==='2'||scope.row.dclass==='1'" :content="scope.row.dclass==='1'?'新建特性':'新建用户故事'">
<el-button @click="showImportFromMenuTemplate(scope.row)" icon="el-icon-upload2" title="批量导入" circle plain size="mini"> </el-button>
</el-tooltip>
</el-tooltip>
</span>
</div>
</template>
@ -271,7 +271,7 @@
</el-table-column>
<el-table-column prop="iterationName" label="迭代" width="150" show-overflow-tooltip sortable>
<template slot-scope="scope">
<div class="cell-text">
<div class="cell-text">
{{scope.row.iterationName}}
</div>
<span class="cell-bar">
@ -322,10 +322,10 @@
<el-button @click="$refs.tagDialog.open({data:scope.row,action:'editTagIds'})">选标签</el-button>
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="mmUsername" label="跟进人" min-width="100" show-overflow-tooltip sortable>
<template slot-scope="scope">
<div class="cell-text">
<div class="cell-text">
{{scope.row.mmUsername}}
</div>
<span class="cell-bar">
@ -339,8 +339,8 @@
</el-row>
<!--编辑 XmMenu xm_project_menu界面-->
<el-dialog title="编辑需求" :visible.sync="editFormVisible" :with-header="false" width="80%" top="20px" center append-to-body :close-on-click-modal="false">
<xm-menu-edit :xm-menu="editForm" :visible="editFormVisible" @cancel="editFormVisible=false" @submit="afterEditSubmit"></xm-menu-edit>
<el-dialog title="编辑需求" :visible.sync="editFormVisible" :with-header="false" width="80%" top="20px" center append-to-body :close-on-click-modal="false" >
<xm-menu-edit :xm-menu="editForm" :visible="editFormVisible" @cancel="editFormVisible=false" @submit="afterEditSubmit" @add-sub-menu="onAddSubMenu" @edit-fields="onEditSomeFields"></xm-menu-edit>
</el-dialog>
<!--新增 XmMenu xm_project_menu界面-->
@ -428,7 +428,7 @@
import {sn} from '@/common/js/sequence'
import { mapGetters } from 'vuex'
import { mapGetters } from 'vuex'
export default {
props:['selProject','xmIteration','xmProduct','disabledMng'],
@ -708,7 +708,7 @@
// XmMenu xm_project_menu
showEdit: function ( row,index ) {
this.editForm = Object.assign({}, row);
this.editForm =row
this.editFormVisible = true;
},
// XmMenu xm_project_menu
@ -722,7 +722,7 @@
this.addFormVisible = true;
}else if(this.filters.iteration && this.filters.iteration.id){
this.parentMenu=null;
this.addForm.productId=this.filters.iteration.productId
this.addForm.productId=this.filters.iteration.productId
this.addForm.iterationId=this.filters.iteration.id
this.addForm.iterationName=this.filters.iteration.iterationName
this.addForm.dclass=dclass
@ -735,10 +735,10 @@
//this.addForm=Object.assign({}, this.editForm);
},
showSubAdd:function(row){
this.addForm={...this.addFormInit}
this.editForm=row
this.parentMenu=row
this.parentMenu=row
this.expandRowKeysCpd.push(row.pmenuId);
this.addForm.productId=row.productId
if(this.filters.product && row.productId==this.filters.product.id){
@ -747,9 +747,9 @@
this.addForm.productName=null;
}
if(this.filters.iteration && this.filters.iteration.id){
this.addForm.productId=this.filters.iteration.productId
this.addForm.productId=this.filters.iteration.productId
this.addForm.iterationId=this.filters.iteration.id
this.addForm.iterationName=this.filters.iteration.iterationName
this.addForm.iterationName=this.filters.iteration.iterationName
this.addFormVisible = true;
}
this.addFormVisible=true
@ -757,20 +757,20 @@
showProdcutAdd:function(){
this.$refs.xmProductMng.showAdd();
},
afterAddSubmit(row){
afterAddSubmit(row){
this.addFormVisible=false;
this.pageInfo.count=true;
//this.getXmMenus();
this.pageInfo.count=true;
//this.getXmMenus();
if(!row.pmenuId){
this.xmMenus.push(row);
}
if(this.parentMenu){
this.parentMenu.childrenCnt=this.parentMenu.childrenCnt?this.parentMenu.childrenCnt+1:1;
}
treeTool.reloadAllChildren(this.$refs.table,this.maps,[row,{...this.parentMenu}],'pmenuId',this.loadXmMenusLazy)
treeTool.reloadAllChildren(this.$refs.table,this.maps,[row,{...this.parentMenu}],'pmenuId',this.loadXmMenusLazy)
this.parentMenu=null;
},
afterEditSubmit(row){
this.editFormVisible=false;
@ -1212,12 +1212,12 @@
var tips = res.data.tips;
if(tips.isOk){
if(this.sels.length>0){
this.sels.forEach(i=>{
this.sels.forEach(i=>{
this.fieldTagVisible=false;
Object.assign(i,params)
Object.assign(i,params)
})
}else{
Object.assign(row,params)
Object.assign(row,params)
}
}else{
this.$notify({showClose:true,message:tips.msg,type:tips.isOk?'success':'error'})
@ -1294,6 +1294,12 @@
}
},
onEditSomeFields(params){
Object.assign(this.editForm,params)
},
onAddSubMenu(row){
treeTool.reloadAllChildren(this.$refs.table,this.maps,[this.editForm,row],'pmenuId',this.loadXmMenusLazy)
}
},//end methods
components: {
@ -1308,7 +1314,7 @@
UsersSelect,
XmMenuMngBatch,
TagDialog,
XmMenuSelect,
XmMenuSelect,
XmMenuWorkload,
XmTableConfig,
XmGroupDialog,

375
src/views/xm/core/xmWorkItem/XmSubBugList.vue

@ -0,0 +1,375 @@
<template>
<el-row v-show="parentXmMenu.dclass==='3' && xmBugs.length>0">
<el-row>
<div class="icon" style="background-color: #F56C6C;">
<i class="el-icon-warning"></i>
</div>
缺陷
<span style="float:right;">
<el-button @click="batchDel" type="danger" icon="el-icon-delete" plain></el-button>
</span>
</el-row>
<el-row>
<el-table :data="xmBugs" :max-height="400" @selection-change="selsChange" @row-click="rowClick">
<el-table-column type="selection" label="全选"></el-table-column>
<el-table-column prop="id" label="缺陷编号" width="100px" show-overflow-tooltip="">
</el-table-column>
<el-table-column prop="name" label="名称" min-width="150px">
</el-table-column>
<el-table-column prop="bugStatus" label="状态" width="100">
<template slot-scope="scope">
<div class="cell-text">
<el-button style="display:block;" :type="item.className" plain round v-for="(item,index) in [formatterBugStatusDicts(scope.row.bugStatus)]" :key="index">{{item.name}}</el-button>
</div>
<span class="cell-bar">
<el-select v-model="scope.row.bugStatus" placeholder="类型" style="display:block;" @change="editXmQuestionSomeFields(scope.row,'bugStatus',$event)">
<el-option :value="item.id" :label="item.name" v-for="(item,index) in dicts.bugStatus" :key="index"></el-option>
</el-select>
</span>
</template>
</el-table-column>
<el-table-column prop="priority" label="优先级" width="100">
<template slot-scope="scope">
<div class="cell-text">
<el-button style="display:block;" :type="item.className" plain round v-for="(item,index) in [formatterPriorityDicts(scope.row.priority)]" :key="index">{{item.name}}</el-button>
</div>
<span class="cell-bar">
<el-select v-model="scope.row.priority" placeholder="优先级" style="display:block;" @change="editXmQuestionSomeFields(scope.row,'priority',$event)">
<el-option :value="item.id" :label="item.name" v-for="(item,index) in dicts.priority" :key="index"></el-option>
</el-select>
</span>
</template>
</el-table-column>
<el-table-column prop="solution" label="解决方案" width="100">
<template slot-scope="scope">
<div class="cell-text">
{{formaterByDicts(scope.row,'solution',scope.row.solution)}}
</div>
<span class="cell-bar">
<el-select v-model="scope.row.solution" placeholder="类型" style="display:block;" @change="editXmQuestionSomeFields(scope.row,'solution',$event)">
<el-option :value="item.id" :label="item.name" v-for="(item,index) in dicts.bugSolution" :key="index"></el-option>
</el-select>
</span>
</template>
</el-table-column>
<el-table-column prop="handlerUsername" label="负责人" width="100" show-overflow-tooltip>
<template slot-scope="scope">
<div class="cell-text">
{{ scope.row.handlerUsername}}
</div>
<span class="cell-bar">
<el-button @click="showGroupUsers('editHandlerUserid',scope.row)">负责人</el-button>
</span>
</template>
</el-table-column>
</el-table>
</el-row>
<xm-group-dialog ref="xmGroupDialog" :sel-project=" {id:linkProjectId} " :is-select-single-user="1" @user-confirm="onUserConfirm"></xm-group-dialog>
</el-row>
</template>
<script>
import Vue from "vue";
import util from "@/common/js/util"; //
import treeTool from "@/common/js/treeTool"; //
import { initSimpleDicts } from '@/api/mdp/meta/item'; //
import { listXmQuestion ,addXmQuestion,batchDelXmQuestion,editXmQuestionSomeFields} from '@/api/xm/core/xmQuestion';
import XmGroupDialog from '../xmGroup/XmGroupDialog';
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(["userInfo", "roles"]),
calcMenuLabel(){
var params={label:'工作项',icon:'',color:''};
if(this.parentXmMenu.dclass==='0'){
params={label:'史诗',icon:'el-icon-s-promotion',color:'rgb(255, 153, 51)'};
}else if(this.parentXmMenu.dclass==='1'){
params={label:'特性',icon:'el-icon-s-flag',color:'rgb(0, 153, 51)'};
}else if(this.parentXmMenu.dclass==='2'){
params={label:'故事',icon:'el-icon-document',color:' rgb(79, 140, 255)'};
}
return params;
},
},
props: [
'parentXmMenu','linkProjectId'
],
watch: {
'parentXmMenu.menuId':function(){
this.initData();
},
'xmBugs':function(){
this.$emit("bugs-change",this.xmBugs)
}
},
data() {
return{
load:{edit:false,list:false,add:false,del:false,},
xmBugs:[],
editForm:null,
sels:[],
dicts:{
priority:[],
bugSeverity:[],
bugSolution:[],
bugStatus:[],
bugType:[],
},
}
}, //end data
methods: {
showGroupUsers:function(userType,row){
this.$refs.xmGroupDialog.open({data:row,action:userType})
},
rowClick: function(row, event, column){
this.editForm=row;
},
//xmQuestion
selsChange: function (sels) {
this.sels = sels;
},
getXmBugs(){
listXmQuestion({menuId:this.parentXmMenu.menuId}).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
this.xmBugs=res.data.data
}else{
this.xmBugs=[];
}
})
},
initData(){
this.xmBugs=[]
if(!this.parentXmMenu || !this.parentXmMenu.menuId){
return;
}
var dclass=this.parentXmMenu.dclass;
if(dclass==='3'){
this.getXmBugs();
}
},
addXmBug(name){
var question={name:name,menuId:this.parentXmMenu.menuId,menuName:this.parentXmMenu.menuName,productId:this.parentXmMenu.productId,iterationId:this.parentXmMenu.iterationId,iterationName:this.parentXmMenu.iterationName}
question.priority='3'
question.verNum=this.parentXmMenu.sinceVersion;
question.pverNum=this.parentXmMenu.sinceVersion;
question.askUserid=this.userInfo.userid
question.askUsername=this.userInfo.username
question.qtype="1"
question.id=null;
question.name=name
question.projectId=this.linkProjectId
question.bugStatus="1"
addXmQuestion(question).then((res) => {
this.load.edit=false
var tips=res.data.tips;
if(tips.isOk){
this.$emit('submit',res.data.data);// @submit="afterAddSubmit"
this.xmBugs.push(res.data.data)
}
this.$notify({showClose: true, message: tips.msg, type: tips.isOk?'success':'error' });
}).catch( err => this.load.edit=false);
},
showAdd() {
this.$prompt('请输入缺陷标题', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(({ value }) => {
this.addXmBug(value);
}).catch(() => {
});
},
batchDel: function () {
if(this.sels.length<=0){
this.$notify({showClose: true, message:"请选择要删除的缺陷", type: "error"});
return ;
}
this.$confirm('确认删除选中记录吗?', '提示', {
type: 'warning'
}).then(() => {
this.load.del=true;
batchDelXmQuestion(this.sels).then((res) => {
this.load.del=false;
var tips=res.data.tips;
if( tips.isOk ){
this.getXmBugs();
}
this.$notify({showClose: true, message: tips.msg, type: tips.isOk?'success':'error'});
}).catch( err => this.load.del=false );
});
},
editXmQuestionSomeFields(row,fieldName,$event){
debugger;
var params={ids:[row.id]};
if(this.sels.length>0){
if(!this.sels.some(k=>k.id==row.id)){
this.$notify({showClose:true,message:'请操作选中的行或者取消选中的行再操作其它行',type:'warning'})
return;
}
params.ids=this.sels.map(i=>i.id)
}
if(fieldName==='handlerUserid'){
if($event){
params[fieldName]=$event[0].userid;
params.handlerUsername=$event[0].username
}else{
return;
}
}else if(fieldName==='tagIds'){
if($event){
params[fieldName]=$event.map(i=>i.tagId).join(",");
params.tagNames=$event.map(i=>i.tagName).join(",");
}else{
return;
}
}else if(fieldName==='workload'){
params={...params,...$event}
}else if(fieldName==='projectId'){
params.projectId=$event.id
}else if(fieldName==='productId'){
params.productId=$event.id
}else{
params[fieldName]=$event
}
editXmQuestionSomeFields(params).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
if(this.sels.length>0){
this.sels.forEach(i=>{
Object.assign(i,params)
})
}else{
Object.assign(row,params)
}
}else{
this.$notify({showClose:true,message:tips.msg,type:tips.isOk?'success':'error'})
}
})
},
onUserConfirm:function(groupUsers,option){
if(option.action=='editHandlerUserid'){
this.editXmQuestionSomeFields(option.data,"handlerUserid",groupUsers)
return;
}
this.getXmBugs();
},
formatterPriorityDicts(cellValue){
var key="priority";
if(this.dicts[key]==undefined || this.dicts[key]==null || this.dicts[key].length==0 ){
return {id:cellValue,name:cellValue,className:'primary'};
}
var list=this.dicts[key].filter(i=>i.id==cellValue)
if(list.length>0){
var data= {...list[0],className:'primary'}
if(data.id=='0'){
data.className='danger'
}else if(data.id=='1'){
data.className='warning'
}else if(data.id=='2'){
data.className='success'
}else if(data.id=='3'){
data.className='primary'
}else if(data.id=='4'){
data.className='info'
}else{
data.className='primary'
}
return data;
}else{
return {id:cellValue,name:cellValue,className:'primary'}
}
},
formatterBugStatusDicts: function(cellValue){
var key="bugStatus";
if(this.dicts[key]==undefined || this.dicts[key]==null || this.dicts[key].length==0 ){
return {id:cellValue,name:cellValue,className:'primary'};
}
var list=this.dicts[key].filter(i=>i.id==cellValue)
if(list.length>0){
var data= {...list[0],className:'primary'}
if(data.id=='1'){
data.className='primary'
}else if(data.id=='2'){
data.className='primary'
}else if(data.id=='3'){
data.className='success'
}else if(data.id=='4'){
data.className='warning'
}else if(data.id=='5'){
data.className='success'
}else if(data.id=='6'){
data.className='info'
}else if(data.id=='7'){
data.className='info'
}else{
data.className='danger'
}
return data;
}else{
return {id:cellValue,name:cellValue,className:'primary'}
}
},
/**
* 'bugSeverity','bugSolution','bugStatus','bugType','priority'bugRepRate
*/
formaterByDicts(row,property,cellValue){
var property=property
var dict=null;
if(property=='bugSeverity'){
dict=this.dicts['bugSeverity']
}else if(property=='solution'){
dict=this.dicts['bugSolution']
}else if(property=='bugStatus'){
dict=this.dicts['bugStatus']
}else if(property=='priority'){
dict=this.dicts['priority']
}else if(property=='bugType'){
dict=this.dicts['bugType']
}else if(property=='repRate'){
dict=this.dicts['bugRepRate']
}
if(!dict){
return cellValue;
}else{
var item=dict.find(i=>i.id==cellValue)
return item?item.name:cellValue;
}
},
}, //end methods
components: {
XmGroupDialog,
},
mounted() {
this.initData();
initSimpleDicts('all',['bugSeverity','bugSolution','bugStatus','bugType','priority','bugRepRate']).then(res=>{
if(res.data.tips.isOk){
this.dicts=res.data.data;
}
});
},
};
</script>
<style scoped>
</style>

134
src/views/xm/core/xmWorkItem/XmSubMenuList.vue

@ -0,0 +1,134 @@
<template>
<section>
<el-row v-if="parentXmMenu.dclass<'3' && xmMenus.length>0">
<el-row v-if="parentXmMenu.dclass==='1'">
<div class="icon" style="background-color: rgb(0, 153, 51);">
<i class="el-icon-s-flag"></i>
</div>特性
</el-row>
<el-row v-if="parentXmMenu.dclass==='2'">
<div class="icon" :style="{backgroundColor: calcMenuLabel.color }">
<i :class="calcMenuLabel.icon"></i>
</div>
用户故事
</el-row>
<el-row>
<el-table :data="xmMenus" :show-header="false" :max-height="400">
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column prop="menuName" label="名称"></el-table-column>
</el-table>
</el-row>
</el-row>
</section>
</template>
<script>
import Vue from "vue";
import util from "@/common/js/util"; //
import treeTool from "@/common/js/treeTool"; //
import { initSimpleDicts } from '@/api/mdp/meta/item'; //
import { listXmMenu,addXmMenu } from '@/api/xm/core/xmMenu';
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(["userInfo", "roles"]),
calcMenuLabel(){
var params={label:'工作项',icon:'',color:''};
if(this.parentXmMenu.dclass==='0'){
params={label:'史诗',icon:'el-icon-s-promotion',color:'rgb(255, 153, 51)'};
}else if(this.parentXmMenu.dclass==='1'){
params={label:'特性',icon:'el-icon-s-flag',color:'rgb(0, 153, 51)'};
}else if(this.parentXmMenu.dclass==='2'){
params={label:'故事',icon:'el-icon-document',color:' rgb(79, 140, 255)'};
}
return params;
},
},
props: [
'parentXmMenu'
],
watch: {
'parentXmMenu.menuId':function(){
this.initData();
},
'xmMenus':function(){
this.$emit('menus-change',this.xmMenus);
}
},
data() {
return{
load:{edit:false,list:false,add:false},
xmMenus:[],
}
}, //end data
methods: {
getXmMenus(){
listXmMenu({pmenuId:this.parentXmMenu.menuId}).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
this.xmMenus=res.data.data
}else{
this.xmMenus=[];
}
})
},
initData(){
this.xmMenus=[]
if(!this.parentXmMenu || !this.parentXmMenu.menuId){
return;
}
var dclass=this.parentXmMenu.dclass;
if(dclass<3){
this.getXmMenus();
}
},
addXmMenu(name){
var menu={...this.parentXmMenu}
menu.mmUserid=this.userInfo.userid
menu.mmUsername=this.userInfo.username
menu.seqNo=this.parentXmMenu.seqNo+"."+(parseInt(this.parentXmMenu.childrenCnt)+1)
menu.pmenuId=this.parentXmMenu.menuId
menu.pmenuName=this.parentXmMenu.menuName
menu.dclass=(parseInt(this.parentXmMenu.dclass)+1)+'';
menu.menuId=null;
menu.menuName=name
addXmMenu(menu).then((res) => {
this.load.edit=false
var tips=res.data.tips;
if(tips.isOk){
this.$emit('add-submit',res.data.data);// @submit="afterAddSubmit"
this.xmMenus.push(res.data.data)
}
this.$notify({showClose: true, message: tips.msg, type: tips.isOk?'success':'error' });
}).catch( err => this.load.edit=false);
},
showAdd() {
this.$prompt('请输入标题', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(({ value }) => {
this.addXmMenu(value);
}).catch(() => {
});
},
}, //end methods
components: {
},
mounted() {
this.initData();
},
};
</script>
<style scoped>
</style>

129
src/views/xm/core/xmWorkItem/XmSubTaskList.vue

@ -0,0 +1,129 @@
<template>
<el-row v-if="parentXmMenu.dclass==='3' && xmTasks.length>0">
<el-row>
<div class="icon" style="background-color: #1CC7EA;">
<i class="el-icon-s-operation"></i>
</div>
任务
</el-row>
<el-row>
<el-table :data="xmTasks" :show-header="false" :max-height="400">
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
</el-row>
</el-row>
</template>
<script>
import Vue from "vue";
import util from "@/common/js/util"; //
import treeTool from "@/common/js/treeTool"; //
import { initSimpleDicts } from '@/api/mdp/meta/item'; //
import { listXmTask ,addTask } from '@/api/xm/core/xmTask';
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(["userInfo", "roles"]),
calcMenuLabel(){
var params={label:'工作项',icon:'',color:''};
if(this.parentXmMenu.dclass==='0'){
params={label:'史诗',icon:'el-icon-s-promotion',color:'rgb(255, 153, 51)'};
}else if(this.parentXmMenu.dclass==='1'){
params={label:'特性',icon:'el-icon-s-flag',color:'rgb(0, 153, 51)'};
}else if(this.parentXmMenu.dclass==='2'){
params={label:'故事',icon:'el-icon-document',color:' rgb(79, 140, 255)'};
}
return params;
},
},
props: [
'parentXmMenu','linkProjectId'
],
watch: {
'parentXmMenu.menuId':function(){
this.initData();
},
'xmTasks':function(){
this.$emit("bugs-change",this.xmTasks)
}
},
data() {
return{
load:{edit:false,list:false,add:false},
xmTasks:[],
}
}, //end data
methods: {
getXmTasks(){
listXmTask({menuId:this.parentXmMenu.menuId}).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
this.xmTasks=res.data.data
}else{
this.xmTasks=[];
}
})
},
initData(){
this.xmTasks=[]
if(!this.parentXmMenu || !this.parentXmMenu.menuId){
return;
}
var dclass=this.parentXmMenu.dclass;
if(dclass==='3'){
this.getXmTasks();
}
},
addXmTask(name){
var task={name:name,menuId:this.parentXmMenu.menuId,menuName:this.parentXmMenu.menuName,productId:this.parentXmMenu.productId,iterationId:this.parentXmMenu.iterationId,iterationName:this.parentXmMenu.iterationName}
task.priority='3'
task.verNum=this.parentXmMenu.sinceVersion;
task.pverNum=this.parentXmMenu.sinceVersion;
task.askUserid=this.userInfo.userid
task.askUsername=this.userInfo.username
task.qtype="1"
task.ntype="0"
task.ptype="0"
task.id=null;
task.name=name
task.projectId=this.linkProjectId
addTask(task).then((res) => {
this.load.edit=false
var tips=res.data.tips;
if(tips.isOk){
this.$emit('submit',res.data.data);// @submit="afterAddSubmit"
this.xmTasks.push(res.data.data)
}
this.$notify({showClose: true, message: tips.msg, type: tips.isOk?'success':'error' });
}).catch( err => this.load.edit=false);
},
showAdd() {
this.$prompt('请输入任务标题', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(({ value }) => {
this.addXmTask(value);
}).catch(() => {
});
},
}, //end methods
components: {
},
mounted() {
this.initData();
},
};
</script>
<style scoped>
</style>

207
src/views/xm/core/xmWorkItem/XmSubWorkItem.vue

@ -1,9 +1,10 @@
<template>
<section class="padding">
<el-row>
<font>{{subWorkItemNum}}个子工作项</font>
<font>{{subWorkItemNum}}个子工作项</font> &nbsp;&nbsp;
<span style="float:right;">
<el-button v-if="parentXmMenu.dclass==='1'" icon="el-icon-plus" @click="showAdd(2)">
<xm-project-select style="display:inline;" v-if="parentXmMenu&&parentXmMenu.menuId && parentXmMenu.dclass==='3' && !linkProjectId" :link-product-id="parentXmMenu.productId" @row-click="xmProject=$event"></xm-project-select>
<el-button v-if="parentXmMenu.dclass==='1'" icon="el-icon-plus" @click="showAdd(2)">
<div class="icon" style="background-color: rgb(0, 153, 51);">
<i class="el-icon-s-flag"></i>
</div> 添加特性
@ -11,71 +12,28 @@
<el-button v-if="parentXmMenu.dclass==='2'" icon="el-icon-plus" @click="showAdd(3)">
<div class="icon" :style="{backgroundColor: calcMenuLabel.color }">
<i :class="calcMenuLabel.icon"></i>
</div>
</div>
添加用户故事
</el-button>
<el-button v-if="parentXmMenu.dclass==='3'" icon="el-icon-plus" @click="showAdd('4')">
<div class="icon" style="background-color: #1CC7EA;">
<i class="el-icon-s-operation"></i>
</div>
添加任务</el-button>
<el-button v-if="parentXmMenu.dclass==='3'" icon="el-icon-plus" @click="showAdd('5')">
<div class="icon" style="background-color: #F56C6C;">
<i class="el-icon-warning"></i>
</div>
添加缺陷</el-button>
</span>
</el-row>
<el-row v-if="parentXmMenu.dclass<'3' && xmMenus.length>0">
<el-row v-if="parentXmMenu.dclass==='1'">
<div class="icon" style="background-color: rgb(0, 153, 51);">
<i class="el-icon-s-flag"></i>
</div>特性
</el-row>
<el-row v-if="parentXmMenu.dclass==='2'">
<div class="icon" :style="{backgroundColor: calcMenuLabel.color }">
<i :class="calcMenuLabel.icon"></i>
</div>
用户故事
</el-row>
<el-row>
<el-table :data="xmMenus" :show-header="false" :max-height="400">
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column prop="menuName" label="名称"></el-table-column>
</el-table>
</el-row>
</el-row>
<el-row v-if="parentXmMenu.dclass==='3' && xmTasks.length>0">
<el-row>
<div class="icon" style="background-color: #1CC7EA;">
<i class="el-icon-s-operation"></i>
</div>
任务</el-row>
<el-row>
<el-table :data="xmTasks" :show-header="false" :max-height="400">
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
</el-row>
</el-row>
<el-row v-if="parentXmMenu.dclass==='3' && xmBugs.length>0">
<el-row>
<div class="icon" style="background-color: #F56C6C;">
<i class="el-icon-warning"></i>
</div>
缺陷</el-row>
<el-row>
<el-table :data="xmBugs" :show-header="false" :max-height="400">
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
</el-row>
</el-row>
<xm-sub-menu-list ref="menuList" :link-project-id="linkProjectId?linkProjectId:(xmProject?xmProject.id:null)" :parentXmMenu="parentXmMenu" @menus-change="onMenusChange" @add-submit="$emit('add-sub-menu',$event)"></xm-sub-menu-list>
<xm-sub-task-list ref="taskList" :link-project-id="linkProjectId?linkProjectId:(xmProject?xmProject.id:null)" :parentXmMenu="parentXmMenu" @tasks-change="onTasksChange"></xm-sub-task-list>
<xm-sub-bug-list class="padding-top" ref="bugList" :link-project-id="linkProjectId?linkProjectId:(xmProject?xmProject.id:null)" :parentXmMenu="parentXmMenu" @bugs-change="onBugsChange"></xm-sub-bug-list>
</section>
</template>
@ -84,19 +42,18 @@ import Vue from "vue";
import util from "@/common/js/util"; //
import treeTool from "@/common/js/treeTool"; //
import { initSimpleDicts } from '@/api/mdp/meta/item'; //
import {
listXmTask,
} from "@/api/xm/core/xmTask";
import { listXmQuestion} from '@/api/xm/core/xmQuestion';
import { listXmMenu,addXmMenu } from '@/api/xm/core/xmMenu';
import { mapGetters } from 'vuex'
import XmSubMenuList from './XmSubMenuList.vue'
import XmSubTaskList from './XmSubTaskList.vue'
import XmSubBugList from './XmSubBugList.vue'
import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect'
export default {
computed: {
...mapGetters(["userInfo", "roles"]),
calcMenuLabel(){
...mapGetters(["userInfo", "roles"]),
calcMenuLabel(){
var params={label:'工作项',icon:'',color:''};
if(this.parentXmMenu.dclass==='0'){
params={label:'史诗',icon:'el-icon-s-promotion',color:'rgb(255, 153, 51)'};
@ -104,129 +61,77 @@ export default {
params={label:'特性',icon:'el-icon-s-flag',color:'rgb(0, 153, 51)'};
}else if(this.parentXmMenu.dclass==='2'){
params={label:'故事',icon:'el-icon-document',color:' rgb(79, 140, 255)'};
}
}
return params;
},
},
subWorkItemNum(){
var num= this.xmTasks.length+this.xmMenus.length+this.xmBugs.length;
this.$emit('sub-work-item-num',num);
return num;
}
},
props: [
'parentXmMenu'
props: [
'parentXmMenu','linkProjectId'
],
watch: {
watch: {
'parentXmMenu.menuId':function(){
this.initData();
}
},
data() {
data() {
return{
load:{edit:false,list:false,add:false},
xmTasks:[],
xmBugs:[],
xmMenus:[],
xmProject:null,
}
}, //end data
methods: {
getXmTasks(){
listXmTask({menuId:this.parentXmMenu.menuId}).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
this.xmTasks=res.data.data
}else{
this.xmTasks=[];
}
})
},
getXmMenus(){
listXmMenu({pmenuId:this.parentXmMenu.menuId}).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
this.xmMenus=res.data.data
}else{
this.xmMenus=[];
}
})
},
getXmBugs(){
listXmQuestion({menuId:this.parentXmMenu.menuId}).then(res=>{
var tips = res.data.tips;
if(tips.isOk){
this.xmBugs=res.data.data
}else{
this.xmBugs=[];
}
})
},
initData(){
initData(){
this.xmTasks=[]
this.xmMenus=[]
this.xmBugs=[]
if(!this.parentXmMenu || !this.parentXmMenu.menuId){
return;
}
var dclass=this.parentXmMenu.dclass;
if(dclass<3){
this.getXmMenus();
}else{
this.getXmTasks();
this.getXmBugs();
}
},
addXmMenu(name){
debugger;
var menu={...this.parentXmMenu}
menu.mmUserid=this.userInfo.userid
menu.mmUsername=this.userInfo.username
menu.seqNo=this.parentXmMenu.seqNo+"."+(parseInt(this.parentXmMenu.childrenCnt)+1)
menu.pmenuId=this.parentXmMenu.menuId
menu.pmenuName=this.parentXmMenu.menuName
menu.dclass=(parseInt(this.parentXmMenu.dclass)+1)+'';
menu.menuId=null;
menu.menuName=name
addXmMenu(menu).then((res) => {
this.load.edit=false
var tips=res.data.tips;
if(tips.isOk){
this.$emit('submit',res.data.data);// @submit="afterAddSubmit"
this.xmMenus.push(res.data.data)
}
this.$notify({showClose: true, message: tips.msg, type: tips.isOk?'success':'error' });
}).catch( err => this.load.edit=false);
},
showAdd(dclass) {
this.$prompt('请输入标题', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(({ value }) => {
if(dclass<4){
this.addXmMenu(value);
}else if(dclass==='4'){
this.addXmTask(value);
}else if(dclass==='5'){
this.addXmQuestion(value);
}
}).catch(() => {
});
if(dclass<4){
this.$refs.menuList.showAdd();
}else if(dclass==='4'){
if(!this.linkProjectId && !this.xmProject){
this.$notify({showClose:true,message:'请先选择一个项目',type:'warning'})
return;
}
this.$refs.taskList.showAdd();
}else if(dclass==='5'){
if(!this.linkProjectId && !this.xmProject){
this.$notify({showClose:true,message:'请先选择一个项目',type:'warning'})
return;
}
this.$refs.bugList.showAdd();
}
},
onMenusChange(menus){
this.xmMenus=menus
},
onBugsChange(bugs){
this.xmBugs=bugs
},
onTasksChange(tasks){
this.xmTasks=tasks
}
/**end 自定义函数请在上面加**/
}, //end methods
components: {
components: {
XmSubMenuList,XmSubTaskList,XmSubBugList,XmProjectSelect
},
mounted() {
mounted() {
this.initData();
},
};
</script>
<style scoped>
<style scoped>
</style>
Loading…
Cancel
Save