13 changed files with 857 additions and 10 deletions
-
182src/router/routes_xm.js
-
41src/views/xm/core/xmContract/XmContractForProduct.vue
-
40src/views/xm/core/xmFile/XmFileForProduct.vue
-
2src/views/xm/core/xmFile/XmFileMng.vue
-
42src/views/xm/core/xmGroup/XmGroupForProduct.vue
-
6src/views/xm/core/xmProduct/XmProductMng.vue
-
4src/views/xm/core/xmProduct/XmProductOverviewComplex.vue
-
68src/views/xm/core/xmProduct/index.vue
-
351src/views/xm/core/xmProduct/top-nav.vue
-
44src/views/xm/core/xmQuestion/XmQuestionForProduct.vue
-
40src/views/xm/core/xmRecord/XmRecordForProduct.vue
-
3src/views/xm/core/xmRecord/XmRecordMng.vue
-
40src/views/xm/rpt/reportIndexForProduct.vue
@ -0,0 +1,41 @@ |
|||
<template> |
|||
<section> |
|||
<xm-contract-mng :xm-product="xmProduct"></xm-contract-mng> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { mapGetters } from 'vuex'; |
|||
import XmContractMng from './XmContractMng.vue' |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles','xmProduct' |
|||
]), |
|||
}, |
|||
watch:{ |
|||
|
|||
}, |
|||
data() { |
|||
return { |
|||
} |
|||
},//end data |
|||
methods: { |
|||
|
|||
|
|||
},//end methods |
|||
components: { |
|||
XmContractMng, |
|||
//在下面添加其它组件 |
|||
}, |
|||
activated(){ |
|||
}, |
|||
mounted() { |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
|||
@ -0,0 +1,40 @@ |
|||
<template> |
|||
<section> |
|||
<xm-file-mng :xm-product="xmProduct"></xm-file-mng> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { mapGetters } from 'vuex'; |
|||
import XmFileMng from './XmFileMng' |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles','xmProduct' |
|||
]), |
|||
}, |
|||
watch:{ |
|||
|
|||
}, |
|||
data() { |
|||
return { |
|||
} |
|||
},//end data |
|||
methods: { |
|||
|
|||
},//end methods |
|||
components: { |
|||
XmFileMng, |
|||
//在下面添加其它组件 |
|||
}, |
|||
activated(){ |
|||
}, |
|||
mounted() { |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
|||
@ -0,0 +1,42 @@ |
|||
<template> |
|||
<section class="padding"> |
|||
<xm-group-mng :xm-product="xmProduct" :visible="xmProduct && xmProduct.id"></xm-group-mng> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
|
|||
import { listXmProject } from '@/api/xm/core/xmProject'; |
|||
import { mapGetters } from 'vuex'; |
|||
import XmGroupMng from './XmGroupMng' |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles','xmProduct' |
|||
]), |
|||
}, |
|||
watch:{ |
|||
|
|||
}, |
|||
data() { |
|||
return { |
|||
} |
|||
},//end data |
|||
methods: { |
|||
|
|||
},//end methods |
|||
components: { |
|||
XmGroupMng, |
|||
//在下面添加其它组件 |
|||
}, |
|||
activated(){ |
|||
}, |
|||
mounted() { |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
|||
@ -0,0 +1,68 @@ |
|||
<template> |
|||
<section> |
|||
<top-nav/> |
|||
<keep-alive><router-view></router-view></keep-alive> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from "@/common/js/util"; //全局公共库 |
|||
//import Sticky from '@/components/Sticky' // 粘性header组件 |
|||
//import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from "vuex"; |
|||
import topNav from './top-nav.vue' |
|||
import store from '@/store' |
|||
import { listXmProduct } from '@/api/xm/core/xmProduct'; |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapGetters(["userInfo", "roles","xmProduct"]), |
|||
}, |
|||
watch: {}, |
|||
data() { |
|||
return { |
|||
}; |
|||
}, //end data |
|||
methods: { |
|||
|
|||
}, //end methods |
|||
components: { |
|||
topNav |
|||
//在下面添加其它组件 |
|||
}, |
|||
mounted() { |
|||
if(!this.$route.query.productId){ |
|||
this.$message.error("地址不合规") |
|||
this.$route.back(-1) |
|||
} |
|||
if(!this.xmProduct||this.xmProduct.id!=this.$route.query.productId){ |
|||
listXmProduct({id:this.$route.query.productId}).then(res=>{ |
|||
var tips = res.data.tips; |
|||
if(tips.isOk ){ |
|||
if( res.data.data.length==1){ |
|||
store.dispatch('setXmProduct',res.data.data[0]) |
|||
}else{ |
|||
this.$message.error("产品不存在,请确保产品编号正确") |
|||
this.$router.push({ |
|||
path:'/xm/core/xmProduct/XmProductMng' |
|||
}) |
|||
} |
|||
|
|||
}else{ |
|||
this.$message.error(tips.msg) |
|||
this.$router.push({ |
|||
path:'/xm/core/xmProduct/XmProductMng' |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
}, |
|||
beforeDestroy(){ |
|||
store.dispatch('setXmProduct',null) |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style rel="stylesheet/scss" lang="scss" scoped> |
|||
|
|||
</style> |
|||
@ -0,0 +1,351 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<el-menu |
|||
:default-active="infotype" |
|||
mode="horizontal" |
|||
@select="setInfotype" |
|||
class="menus" |
|||
background-color="rgb(48, 65, 86)" |
|||
text-color="rgb(191, 203, 217)" |
|||
active-text-color="#409eff" |
|||
:router="true" |
|||
> |
|||
|
|||
<el-menu-item :index="'/xm/core/product/overview?productId='+xmProduct.id"> |
|||
<span |
|||
slot="title" |
|||
style="font-size: 18px; color: #ffd04b" |
|||
class="hidden-sm-and-down" |
|||
:title="xmProduct.productName" |
|||
> |
|||
<font v-if="xmProduct.productName.length >= 15" |
|||
><strong |
|||
> <el-avatar class="top-icon" icon="el-icon-odometer" style="background-color:#E6A23C"></el-avatar> 项目: {{ xmProduct.productName.substring(0, 15) }}</strong |
|||
></font |
|||
> |
|||
<font type="danger" v-else |
|||
><strong> <el-avatar class="top-icon" icon="el-icon-odometer" style="background-color:#E6A23C"></el-avatar> 项目: {{ xmProduct.productName }}</strong></font |
|||
> |
|||
</span> |
|||
|
|||
<span |
|||
slot="title" |
|||
style="color: #ffd04b" |
|||
class="hidden-md-and-up" |
|||
:title="xmProduct.productName" |
|||
> |
|||
<font v-if="xmProduct.productName.length >= 15" |
|||
> <el-avatar class="top-icon" icon="el-icon-odometer" style="background-color:#E6A23C"></el-avatar> 项目: {{ xmProduct.productName.substring(0, 15) }}</font |
|||
> |
|||
<font type="danger" v-else |
|||
> <el-avatar class="top-icon" icon="el-icon-odometer" style="background-color:#E6A23C"></el-avatar> 项目: {{ xmProduct.productName }}</font |
|||
> |
|||
</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/project?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-s-opportunity"></i>项目</span> |
|||
</el-menu-item> |
|||
<el-menu-item label="需求" :index="'/xm/core/product/menu?productId='+xmProduct.id" class="hidden-md-and-down"> |
|||
<span slot="title"><i class="el-icon-document"></i>需求</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/iteration?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-connection"></i>迭代</span> |
|||
</el-menu-item> |
|||
|
|||
<el-menu-item :index="'/xm/core/product/plan?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-time"></i>计划</span> |
|||
</el-menu-item> |
|||
|
|||
<el-menu-item :index="'/xm/core/product/task?productId='+xmProduct.id" class="hidden-md-and-down"> |
|||
<span slot="title"><i class="el-icon-s-operation"></i>任务</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/question?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-question"></i>缺陷</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/group?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-user-solid"></i>团队</span> |
|||
</el-menu-item> |
|||
<el-submenu index="caiwu" class="hidden-sm-and-down"> |
|||
<template slot="title"><i class="el-icon-coin"></i>财务</template> |
|||
<el-menu-item :index="'/xm/core/product/contract?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-s-data"></i>合同管理</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/budget?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-coin"></i>预算</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/cost?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-coin"></i>费用</span> |
|||
</el-menu-item> |
|||
</el-submenu> |
|||
<el-menu-item :index="'/xm/core/product/report?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-s-data"></i>效能</span> |
|||
</el-menu-item> |
|||
<el-submenu index="zhishi" class="hidden-md-and-down"> |
|||
<template slot="title">知识</template> |
|||
<el-menu-item :index="'/xm/core/product/file?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-document"></i>文档</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/env?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-setting"></i>环境清单</span> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/record?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-edit-outline"></i>日志</span> |
|||
</el-menu-item> |
|||
</el-submenu> |
|||
<el-submenu index="更多"> |
|||
<template slot="title">更多 </template> |
|||
<el-menu-item :index="'/xm/core/product/workloadDay?productId='+xmProduct.id"> |
|||
<span slot="title" |
|||
><i class="el-icon-video-camera"></i>每日工时</span |
|||
> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/workloadMonth?productId='+xmProduct.id"> |
|||
<span slot="title" |
|||
><i class="el-icon-video-camera"></i>每月工时</span |
|||
> |
|||
</el-menu-item> |
|||
<el-menu-item :index="'/xm/core/product/env?productId='+xmProduct.id"> |
|||
<span slot="title"><i class="el-icon-setting"></i>环境清单</span> |
|||
</el-menu-item> |
|||
<el-menu-item index="/forum"> |
|||
<span slot="title"><i class="el-icon-date"></i>论坛</span> |
|||
</el-menu-item> |
|||
<el-menu-item index="/im"> |
|||
<span slot="title"><i class="el-icon-date"></i>即聊</span> |
|||
</el-menu-item> |
|||
<el-menu-item index="/helpCenter"> |
|||
<span slot="title"><i class="el-icon-date"></i>客服</span> |
|||
</el-menu-item> |
|||
<el-menu-item index="回到项目列表页" @click.native="goBack"> |
|||
<span slot="title" |
|||
><i class="el-icon-back"></i>回到项目列表页</span |
|||
> |
|||
</el-menu-item> |
|||
<el-menu-item index="首页" @click.native="goHome"> |
|||
<span slot="title" |
|||
><i class="el-icon-s-home"></i>首页</span |
|||
> |
|||
</el-menu-item> |
|||
</el-submenu> |
|||
</el-menu> |
|||
</el-row> |
|||
<!-- |
|||
<el-row ref="pageBody"> |
|||
<el-col :span="infotype=='项目概览'?20:24"> |
|||
<xm-product-overview-complex |
|||
v-if="infotype == '项目概览'" |
|||
:sel-product="xmProduct" |
|||
@submit="afterEditSubmit" |
|||
@edit-fields="onEditFields" |
|||
ref="项目概览" |
|||
></xm-product-overview-complex> |
|||
<xm-product-for-link-complex |
|||
v-if="infotype == '产品'" |
|||
ref="xmProductComplex" |
|||
:sel-product="xmProduct" |
|||
></xm-product-for-link-complex> |
|||
<xm-iteration-for-link-complex |
|||
v-if="infotype == '迭代'" |
|||
ref="xmIterationMng" |
|||
:sel-product="xmProduct" |
|||
></xm-iteration-for-link-complex> |
|||
<xm-menu-mng |
|||
v-if="infotype == '需求'" |
|||
:sel-product="xmProduct" |
|||
></xm-menu-mng> |
|||
<xm-task-mng |
|||
v-if="infotype == '任务'" |
|||
ref="xmTaskMng" |
|||
:sel-product="xmProduct" |
|||
ptype="0" |
|||
queryScope="task" |
|||
key="task" |
|||
></xm-task-mng> |
|||
<xm-question |
|||
v-if="infotype == '缺陷'" |
|||
:qtype="'1'" |
|||
:sel-product="xmProduct" |
|||
ref="xmQuestion" |
|||
></xm-question> |
|||
<xm-group-mng |
|||
v-if="infotype == '团队'" |
|||
:sel-product="xmProduct" |
|||
></xm-group-mng> |
|||
<xm-file-mng |
|||
v-if="infotype == '文档'" |
|||
:sel-product="xmProduct" |
|||
></xm-file-mng> |
|||
<xm-plan |
|||
v-if="infotype == '计划'" |
|||
ref="productPlan" |
|||
ptype="0" |
|||
queryScope="planTask" |
|||
:sel-product="xmProduct" |
|||
key="productPlan" |
|||
></xm-plan> |
|||
<xm-test-case-exec-mng |
|||
v-if="infotype == '测试计划'" |
|||
:visible="infotype == '测试计划'" |
|||
:sel-product="xmProduct" |
|||
ref="xmQuestion" |
|||
></xm-test-case-exec-mng> |
|||
<xm-budget |
|||
v-if="infotype == '预算'" |
|||
:sel-product="xmProduct" |
|||
></xm-budget> |
|||
<xm-cost v-if="infotype == '费用'" :sel-product="xmProduct"></xm-cost> |
|||
<xm-product-kpi |
|||
v-if="infotype == '考核'" |
|||
:sel-product="xmProduct" |
|||
></xm-product-kpi> |
|||
<xm-record |
|||
v-if="infotype == '日志'" |
|||
:visible="infotype == '日志'" |
|||
:sel-product="xmProduct" |
|||
></xm-record> |
|||
<xm-contract |
|||
v-if="infotype == '合同管理'" |
|||
:sel-product="xmProduct" |
|||
></xm-contract> |
|||
<xm-env-list |
|||
v-if="infotype == '环境清单'" |
|||
:sel-product="xmProduct" |
|||
></xm-env-list> |
|||
<xm-question |
|||
v-if="infotype == '风险'" |
|||
:qtype="'2'" |
|||
:sel-product="xmProduct" |
|||
ref="xmRisk" |
|||
></xm-question> |
|||
<el-drawer |
|||
title="选中团队成员" |
|||
:visible.sync="groupUserVisible" |
|||
size="50%" |
|||
append-to-body |
|||
:close-on-click-modal="false" |
|||
> |
|||
<xm-group-select |
|||
:sel-product="xmProduct" |
|||
:visible="groupUserVisible" |
|||
is-select-multi-user="1" |
|||
@user-confirm="onUserSelected" |
|||
></xm-group-select> |
|||
</el-drawer> |
|||
|
|||
<xm-report |
|||
v-if="infotype == '效能'" |
|||
:xm-product="xmProduct" |
|||
></xm-report> |
|||
|
|||
<xm-workload-set-day-list |
|||
v-if="infotype == '每日工时'" |
|||
:xm-product="xmProduct" |
|||
></xm-workload-set-day-list> |
|||
|
|||
<xm-workload-set-month-list |
|||
v-if="infotype == '每月工时'" |
|||
:xm-product="xmProduct" |
|||
></xm-workload-set-month-list> |
|||
</el-col> |
|||
</el-row> |
|||
--> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
|
|||
import { mapGetters } from 'vuex' |
|||
|
|||
export default { |
|||
props: ["visible"], |
|||
computed: { |
|||
...mapGetters(["userInfo", "roles","xmProduct"]), |
|||
|
|||
calcProjectStatusStep() { |
|||
if (this.dicts["productStatus"] && this.xmProduct) { |
|||
var index = this.dicts["productStatus"].findIndex((i) => { |
|||
if (i.id == this.xmProduct.status) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
}); |
|||
return index + 1; |
|||
} else { |
|||
return 0; |
|||
} |
|||
}, |
|||
}, |
|||
watch: { |
|||
$route:{ |
|||
handler(newVal,oldValu){ |
|||
this.infotype=newVal.fullPath |
|||
}, |
|||
deep:true, |
|||
immediate:true, |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
infotype:'', |
|||
}; |
|||
}, //end data |
|||
methods: { |
|||
setInfotype(infotype) { |
|||
this.infotype = infotype; |
|||
}, |
|||
/** |
|||
* 防止禁用弹框 _self模式 |
|||
* @param {} url |
|||
*/ |
|||
newWin(url) { |
|||
var id='toOpenWindow' |
|||
var a = document.createElement('a'); |
|||
a.setAttribute('href', url); |
|||
a.setAttribute('target', '_self'); |
|||
a.setAttribute('id', id); |
|||
// 防止反复添加 |
|||
if(!document.getElementById(id)) document.body.appendChild(a); |
|||
a.click(); |
|||
}, |
|||
toForum(){ |
|||
this.newWin('https://www.maimengcloud.com/#/communityForum'); |
|||
}, |
|||
goBack() { |
|||
this.$router.push({ |
|||
path:'/xm/core/xmProduct/XmProductMng' |
|||
}) |
|||
}, |
|||
goHome(){ |
|||
this.$router.push({path:'/'}) |
|||
}, |
|||
|
|||
}, //end methods |
|||
components: { |
|||
|
|||
//在下面添加其它组件 |
|||
}, |
|||
mounted() { |
|||
this.infotype=this.$route.fullPath |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style rel="stylesheet/scss" lang="scss" scoped> |
|||
.menus { |
|||
.el-menu-item { |
|||
padding-left: 0px !important; |
|||
} |
|||
} |
|||
/* 超过宽度则用...代替 */ |
|||
.truncate { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
.step-btn{ |
|||
margin-left:0px;margin-bottom: 5px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,44 @@ |
|||
<template> |
|||
<xm-question-mng class="padding-top" :xm-product="xmProduct"></xm-question-mng> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
|
|||
import config from '@/common/config';//全局公共库 |
|||
|
|||
import XmQuestionMng from './XmQuestionMng';//修改界面 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles','xmProduct' |
|||
]), |
|||
}, |
|||
|
|||
data() { |
|||
|
|||
return { |
|||
|
|||
|
|||
} |
|||
|
|||
},//end data |
|||
methods: { |
|||
|
|||
|
|||
},//end methods |
|||
components: { |
|||
XmQuestionMng |
|||
}, |
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
|
|||
</style> |
|||
@ -0,0 +1,40 @@ |
|||
<template> |
|||
<section> |
|||
<xm-record-mng :xm-product="xmProduct"></xm-record-mng> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { mapGetters } from 'vuex'; |
|||
import XmRecordMng from './XmRecordMng' |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles','xmProduct' |
|||
]), |
|||
}, |
|||
watch:{ |
|||
|
|||
}, |
|||
data() { |
|||
return { |
|||
} |
|||
},//end data |
|||
methods: { |
|||
|
|||
},//end methods |
|||
components: { |
|||
XmRecordMng, |
|||
//在下面添加其它组件 |
|||
}, |
|||
activated(){ |
|||
}, |
|||
mounted() { |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
|||
@ -0,0 +1,40 @@ |
|||
<template> |
|||
<section> |
|||
<report-index :xm-product="xmProduct"></report-index> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { mapGetters } from 'vuex'; |
|||
import reportIndex from './reportIndex' |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles','xmProduct' |
|||
]), |
|||
}, |
|||
watch:{ |
|||
|
|||
}, |
|||
data() { |
|||
return { |
|||
} |
|||
},//end data |
|||
methods: { |
|||
|
|||
},//end methods |
|||
components: { |
|||
reportIndex, |
|||
//在下面添加其它组件 |
|||
}, |
|||
activated(){ |
|||
}, |
|||
mounted() { |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue