9 changed files with 4 additions and 6259 deletions
-
6src/views/xm/core/xmIteration/XmIterationInfo.vue
-
397src/views/xm/core/xmPhase/XmPhaseAdd.vue
-
1772src/views/xm/core/xmPhase/XmPhaseBatch.vue
-
404src/views/xm/core/xmPhase/XmPhaseEdit.vue
-
1290src/views/xm/core/xmPhase/XmPhaseForProduct.vue
-
1328src/views/xm/core/xmPhase/XmPhaseMng.vue
-
576src/views/xm/core/xmPhase/XmPhaseOverview.vue
-
484src/views/xm/core/xmPhase/XmPhaseSelect.vue
-
6src/views/xm/core/xmProduct/XmProductInfo.vue
@ -1,397 +0,0 @@ |
|||||
<template> |
|
||||
<section class="page-container padding"> |
|
||||
<el-row class="page-main "> |
|
||||
<!--新增界面 XmPhase xm_project_phase--> |
|
||||
<el-form :model="addForm" label-width="120px" :rules="addFormRules" ref="addForm"> |
|
||||
<el-row class="border padding"> |
|
||||
<el-form-item label="计划名称" prop="name"> |
|
||||
<el-input v-model="addForm.name" placeholder="计划名称" ></el-input> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="序号" prop="seqNo"> |
|
||||
<el-input v-model="addForm.seqNo" style="width:50%;" placeholder="排序序号,值越小越靠前,如1.0,2.0等"></el-input> |
|
||||
<el-checkbox true-label="1" false-label="0" v-model="addForm.milestone">标记为里程碑</el-checkbox> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="计划类型" prop="planType"> |
|
||||
<el-select v-model="addForm.planType"> |
|
||||
<el-option v-for="i in this.dicts.planType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|
||||
</el-select> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="任务类型" prop="taskType"> |
|
||||
<el-select v-model="addForm.taskType"> |
|
||||
<el-option v-for="i in this.dicts.taskType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|
||||
</el-select> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="备注" prop="remark"> |
|
||||
<el-input type="textarea" rows="4" v-model="addForm.remark" placeholder="备注" ></el-input> |
|
||||
</el-form-item> |
|
||||
|
|
||||
</el-row> |
|
||||
<el-tabs v-model="activeName" class="border padding"> |
|
||||
<el-tab-pane label="工作量及人力成本" name="budgetWorkload"> |
|
||||
<el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-row class="padding">工作量计算方式:<font style="color:red">总工时 = 工作日天数 * 每日工时数 * 人数 </font> </el-row> |
|
||||
<el-row class="padding">金额计算方式: <font style="color:red">总金额 = 总工时 * 工时单价 </font></el-row> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
预计时间:<el-date-picker |
|
||||
v-model="dateRanger" |
|
||||
type="daterange" |
|
||||
align="right" |
|
||||
unlink-panels |
|
||||
range-separator="至" |
|
||||
start-placeholder="计划开始日期" |
|
||||
end-placeholder="计划完成日期" |
|
||||
value-format="yyyy-MM-dd HH:mm:ss" |
|
||||
:default-time="['00:00:00','23:59:59']" |
|
||||
:picker-options="pickerOptions" |
|
||||
></el-date-picker> |
|
||||
预估工期:<el-input style="width:100px;" type="number" v-model="addForm.budgetHours" :precision="2" :step="8" :min="0" placeholder="预计工时"></el-input>小时 |
|
||||
<div class="tips"><font>工时{{autoParams.budgetHours}}小时,工作日{{autoParams.weekday}}天</font></div> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">人员类型</el-col> |
|
||||
<el-col :span="4">人数</el-col> |
|
||||
<el-col :span="4">工作量(人时)</el-col> |
|
||||
<el-col :span="4">单价(元/人时)</el-col> |
|
||||
<el-col :span="8">总价(元)</el-col> |
|
||||
|
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">内购</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="addForm.budgetIuserCnt" :precision="0" :step="1" :min="0" placeholder="内购人数"></el-input> |
|
||||
</el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetIuserWorkload}}人时</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="addForm.budgetIuserPrice" :precision="0" :step="1" :min="0" placeholder="预计内部人时单价"></el-input> </el-col> |
|
||||
<el-col :span="8">{{this.toFixed(autoParams.budgetIuserAt)}}元,{{this.toFixed(autoParams.budgetIuserAt/10000)}} 万元</el-col> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">外购</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="addForm.budgetOuserCnt" :precision="0" :step="1" :min="0" placeholder="外购人数"></el-input> |
|
||||
</el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetOuserWorkload}}人时</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="addForm.budgetOuserPrice" :precision="0" :step="1" :min="0" placeholder="预计外购人时单价"></el-input> </el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetOuserAt }} 元 {{autoParams.budgetOuserAt/10000 }}万元</el-col> |
|
||||
|
|
||||
</el-row > |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">合计</el-col> |
|
||||
<el-col :span="4"> {{autoParams.budgetOuserCnt+autoParams.budgetIuserCnt}} |
|
||||
</el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetOuserWorkload+autoParams.budgetIuserWorkload }}人时,{{ (autoParams.budgetOuserWorkload+autoParams.budgetIuserWorkload)/8/20 }}人月 </el-col> |
|
||||
<el-col :span="4">{{ (parseFloat2(autoParams.budgetOuserPrice) + parseFloat2(autoParams.budgetIuserPrice))/2}}元/人时</el-col> |
|
||||
<el-col :span="8">{{autoParams.budgetTotalCost}} 元,{{(autoParams.budgetTotalCost)/10000}} 万元</el-col> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
总计: {{parseFloat2(addForm.budgetIuserAt)+parseFloat2(addForm.budgetOuserAt)+parseFloat2(addForm.budgetNouserAt)}}元 <el-tag>{{this.toFixed(autoParams.budgetTotalCost/10000)}}万元</el-tag> |
|
||||
|
|
||||
</el-row> |
|
||||
</el-row> |
|
||||
</el-tab-pane> |
|
||||
<el-tab-pane v-if="activeName=='budgetWorkload'" label="收起" name=""> |
|
||||
</el-tab-pane> |
|
||||
</el-tabs> |
|
||||
</el-form> |
|
||||
</el-row> |
|
||||
<el-row class="page-bottom"> |
|
||||
<el-button @click.native="handleCancel">取消</el-button> |
|
||||
<el-button v-loading="load.add" type="primary" @click.native="addSubmit" :disabled="load.add==true">提交</el-button> |
|
||||
</el-row> |
|
||||
</section> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import util from '@/common/js/util';//全局公共库 |
|
||||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|
||||
import { addXmPhase } from '@/api/xm/core/xmPhase'; |
|
||||
import { mapGetters } from 'vuex' |
|
||||
|
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapGetters([ |
|
||||
'userInfo','roles' |
|
||||
]), |
|
||||
|
|
||||
autoParams:function(){ |
|
||||
|
|
||||
|
|
||||
var budgetOuserPrice=this.toFixed(this.addForm.budgetOuserPrice) |
|
||||
var budgetIuserPrice=this.toFixed(this.addForm.budgetIuserPrice) |
|
||||
var budgetOuserCnt=this.toFixed(this.addForm.budgetOuserCnt) |
|
||||
var budgetIuserCnt=this.toFixed(this.addForm.budgetIuserCnt) |
|
||||
var budgetHours=this.toFixed(this.addForm.budgetHours ) |
|
||||
var budgetNouserAt=this.toFixed(this.addForm.budgetNouserAt ) |
|
||||
if(budgetOuserPrice==null || budgetOuserPrice==''){ |
|
||||
budgetOuserPrice=100 |
|
||||
} |
|
||||
if(budgetIuserPrice==null || budgetIuserPrice==''){ |
|
||||
budgetIuserPrice=80 |
|
||||
} |
|
||||
if(budgetOuserCnt==null || budgetOuserCnt==''){ |
|
||||
budgetOuserCnt=0.0 |
|
||||
} |
|
||||
if(budgetIuserCnt==null || budgetIuserCnt==''){ |
|
||||
budgetIuserCnt=0.0 |
|
||||
} |
|
||||
|
|
||||
if(budgetNouserAt==null || budgetNouserAt==''){ |
|
||||
budgetNouserAt=0.0 |
|
||||
} |
|
||||
|
|
||||
if(budgetHours==null || budgetHours==''){ |
|
||||
budgetHours=0.0 |
|
||||
} |
|
||||
var autoParams={ |
|
||||
|
|
||||
} |
|
||||
var weekday=1; |
|
||||
if(this.dateRanger!=null && this.dateRanger.length>=2 ){ |
|
||||
weekday=this.getWeekday(new Date(this.dateRanger[0]),new Date(this.dateRanger[1])); |
|
||||
budgetHours=weekday * 8 |
|
||||
|
|
||||
} |
|
||||
autoParams.weekday=weekday |
|
||||
autoParams.budgetHours=budgetHours |
|
||||
autoParams.budgetOuserPrice=budgetOuserPrice |
|
||||
autoParams.budgetIuserPrice=budgetIuserPrice |
|
||||
autoParams.budgetOuserCnt=budgetOuserCnt |
|
||||
autoParams.budgetIuserCnt=budgetIuserCnt |
|
||||
autoParams.budgetIuserWorkload= budgetIuserCnt*budgetHours |
|
||||
autoParams.budgetOuserWorkload= budgetOuserCnt*budgetHours |
|
||||
autoParams.budgetWorkload= budgetIuserCnt*budgetHours + budgetOuserCnt*budgetHours |
|
||||
autoParams.budgetOuserAt= budgetOuserCnt * budgetHours * budgetOuserPrice |
|
||||
autoParams.budgetIuserAt= budgetIuserCnt * budgetHours * budgetIuserPrice |
|
||||
autoParams.budgetNouserAt= budgetNouserAt |
|
||||
autoParams.budgetTotalCost= autoParams.budgetOuserAt + autoParams.budgetIuserAt + autoParams.budgetNouserAt |
|
||||
return autoParams |
|
||||
}, |
|
||||
}, |
|
||||
props:['xmPhase','visible','parentProjectPhase'], |
|
||||
watch: { |
|
||||
'xmPhase':function( xmPhase ) { |
|
||||
this.addForm = xmPhase; |
|
||||
}, |
|
||||
'visible':function(visible) { |
|
||||
if(visible==true){ |
|
||||
//从新打开页面时某些数据需要重新加载,可以在这里添加 |
|
||||
if(this.parentProjectPhase){ |
|
||||
if(this.parentProjectPhase.children){ |
|
||||
this.addForm.seqNo=this.parentProjectPhase.seqNo+"."+(this.parentProjectPhase.children.length+1) |
|
||||
}else{ |
|
||||
this.addForm.seqNo=this.parentProjectPhase.seqNo+"."+1 |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
autoParams:function(autoParams){ |
|
||||
this.fillbudgetHoursToField() |
|
||||
this.fillbudgetAtToField() |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
const beginDate = new Date(); |
|
||||
const endDate = new Date(); |
|
||||
endDate.setTime(beginDate.getTime() + 3600 * 1000 * 24 * 7 * 4); |
|
||||
return { |
|
||||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|
||||
addFormRules: { |
|
||||
id: [ |
|
||||
//{ required: true, message: '计划主键不能为空', trigger: 'blur' } |
|
||||
], |
|
||||
name: [ |
|
||||
{ required: true, message: '计划名称不能为空', trigger: 'blur' } |
|
||||
], |
|
||||
planType: [ |
|
||||
{ required: true, message: '请选择计划类型', trigger: 'blur' } |
|
||||
], |
|
||||
taskType: [ |
|
||||
{ required: true, message: '请选择任务类型', trigger: 'blur' } |
|
||||
], |
|
||||
seqNo: [ |
|
||||
{ required: true, message: '序号不能为空', trigger: 'blur' } |
|
||||
], |
|
||||
}, |
|
||||
//新增界面数据 xm_project_phase |
|
||||
addForm: { |
|
||||
id:'',name:'',remark:'',parentPhaseId:'',branchId:'',taskType:'kf',planType:'m1',projectId:'',beginDate:'',endDate:'',budgetHours:'',budgetStaffNu:'',ctime:'',budgetNouserAt:'',budgetIuserAt:'',budgetOuserAt:'',baselineId:'',bizProcInstId:'',bizFlowState:'',budgetWorkload:'',totalActWorkload:'',totalActNouserAt:'',totalActInerUserAt:'',totalActOuserAt:'',planType:'',taskType:'',seqNo:'1',budgetIuserCnt:'',budgetOuserCnt:'',budgetIuserPrice:80,budgetOuserPrice:100,budgetIuserWorkload:0,budgetOuserWorkload:0,ntype:'0' |
|
||||
}, |
|
||||
dateRanger: [ |
|
||||
util.formatDate(beginDate, "yyyy-MM-dd HH:mm:ss"), |
|
||||
util.formatDate(endDate, "yyyy-MM-dd HH:mm:ss") |
|
||||
], |
|
||||
/**begin 在下面加自定义属性,记得补上面的一个逗号**/ |
|
||||
pickerOptions: util.getPickerOptions('datarange'), |
|
||||
activeName:'', |
|
||||
costVisible:false, |
|
||||
/**end 在上面加自定义属性**/ |
|
||||
}//end return |
|
||||
},//end data |
|
||||
methods: { |
|
||||
// 取消按钮点击 父组件监听@cancel="addFormVisible=false" 监听 |
|
||||
handleCancel:function(){ |
|
||||
//this.$refs['addForm'].resetFields(); |
|
||||
this.$emit('cancel'); |
|
||||
}, |
|
||||
//新增提交XmPhase xm_project_phase 父组件监听@submit="afteraddSubmit" |
|
||||
addSubmit: function () { |
|
||||
|
|
||||
if ( |
|
||||
this.dateRanger != null && |
|
||||
this.dateRanger.length == 2 |
|
||||
) { |
|
||||
if(this.dateRanger[0]){ |
|
||||
if(this.dateRanger[0].length<=10){ |
|
||||
this.addForm.beginDate = this.dateRanger[0] ; |
|
||||
}else{ |
|
||||
this.addForm.beginDate = this.dateRanger[0] |
|
||||
} |
|
||||
} |
|
||||
if(this.dateRanger[1]){ |
|
||||
if(this.dateRanger[1].length<=10){ |
|
||||
this.addForm.endDate = this.dateRanger[1] ; |
|
||||
}else{ |
|
||||
this.addForm.endDate = this.dateRanger[1] |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
}else{ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "请输入开始日期和结束日期", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
if(!this.addForm.budgetIuserCnt){ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "内购人员数不能为空", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if(!this.addForm.budgetHours){ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "工期不能为空", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
if(!this.addForm.budgetIuserPrice){ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "内购单价不能为空", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
this.$refs.addForm.validate((valid) => { |
|
||||
if (valid) { |
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => { |
|
||||
this.load.add=true |
|
||||
let params = Object.assign({}, this.addForm); |
|
||||
if(!params.budgetIuserAt){ |
|
||||
params.budgetIuserAt= this.parseFloat2(params.budgetIuserCnt) * this.parseFloat2(params.budgetIuserPrice) * this.parseFloat2(params.budgetHours) |
|
||||
} |
|
||||
if( !params.budgetOuserAt ){ |
|
||||
params.budgetOuserAt= this.parseFloat2(params.budgetOuserCnt) * this.parseFloat2(params.budgetOuserPrice) * this.parseFloat2(params.budgetHours) |
|
||||
} |
|
||||
params.budgetIuserWorkload= this.parseFloat2(params.budgetIuserCnt) * this.parseFloat2(params.budgetHours) |
|
||||
params.budgetOuserWorkload= this.parseFloat2(params.budgetOuserCnt) * this.parseFloat2(params.budgetHours) |
|
||||
|
|
||||
params.budgetWorkload= this.parseFloat2(params.budgetIuserWorkload) + this.parseFloat2(params.budgetOuserWorkload) |
|
||||
if( !params.budgetStaffNu ){ |
|
||||
|
|
||||
params.budgetStaffNu= this.parseFloat2(params.budgetOuserCnt) + this.parseFloat2(params.budgetIuserCnt) |
|
||||
} |
|
||||
if(this.parentProjectPhase==null || this.parentProjectPhase==undefined){ |
|
||||
|
|
||||
}else{ |
|
||||
params.parentPhaseId=this.parentProjectPhase.id |
|
||||
} |
|
||||
var func=addXmPhase; |
|
||||
if(addForm.phaseClass=='1'){ |
|
||||
func=addXmPhase |
|
||||
} |
|
||||
func(params).then((res) => { |
|
||||
this.load.add=false |
|
||||
var tips=res.data.tips; |
|
||||
if(tips.isOk){ |
|
||||
//this.$refs['addForm'].resetFields(); |
|
||||
this.$emit('submit',res.data.data);// @submit="afteraddSubmit" |
|
||||
} |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: tips.msg, type: tips.isOk?'success':'error' }); |
|
||||
}).catch( err => this.load.add=false); |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
}, |
|
||||
getWeekday(first, last) { |
|
||||
//计算工作日方法:遍历这两个日期区间的每一个日期,获取他的getDay() |
|
||||
|
|
||||
//分别获取first和last的毫秒数(时间戳) |
|
||||
first = first.getTime(); |
|
||||
last = last.getTime(); |
|
||||
|
|
||||
var count = 0; |
|
||||
for (var i = first; i <= last; i += 24 * 3600 * 1000) { |
|
||||
var d = new Date(i); |
|
||||
if (d.getDay() >= 1 && d.getDay() <= 5) { |
|
||||
count++; |
|
||||
} |
|
||||
} |
|
||||
return count; |
|
||||
}, |
|
||||
toFixed(floatValue,num){ |
|
||||
if(floatValue ==null || floatValue=='' || floatValue == undefined){ |
|
||||
return 0; |
|
||||
}else{ |
|
||||
if(!num){ |
|
||||
num=2 |
|
||||
} |
|
||||
return parseFloat(parseFloat(floatValue).toFixed(num)); |
|
||||
} |
|
||||
}, |
|
||||
parseFloat2(floatValue){ |
|
||||
if(floatValue ==null || floatValue=='' || floatValue == undefined){ |
|
||||
return 0; |
|
||||
}else{ |
|
||||
return parseFloat(floatValue); |
|
||||
} |
|
||||
}, |
|
||||
fillToField:function(){ |
|
||||
this.addForm=Object.assign(this.addForm,this.autoParams); |
|
||||
}, |
|
||||
fillbudgetHoursToField:function(){ |
|
||||
this.addForm.budgetHours=this.toFixed(this.autoParams.budgetHours) |
|
||||
}, |
|
||||
|
|
||||
fillbudgetAtToField:function(){ |
|
||||
this.addForm.budgetNouserAt=this.toFixed(this.autoParams.budgetNouserAt) |
|
||||
this.addForm.budgetOuserAt=this.toFixed(this.autoParams.budgetOuserAt ) |
|
||||
this.addForm.budgetIuserAt=this.toFixed(this.autoParams.budgetIuserAt ) |
|
||||
this.addForm.budgetTotalCost=this.toFixed(this.autoParams.budgetTotalCost) |
|
||||
|
|
||||
}, |
|
||||
/**end 在上面加自定义方法**/ |
|
||||
|
|
||||
},//end method |
|
||||
components: { |
|
||||
//在下面添加其它组件 'xm-phase-add':XmPhaseEdit |
|
||||
}, |
|
||||
mounted() { |
|
||||
this.addForm=Object.assign(this.addForm, this.xmPhase); |
|
||||
/**在下面写其它函数***/ |
|
||||
|
|
||||
if(this.parentProjectPhase){ |
|
||||
if(this.parentProjectPhase.childrenCnt){ |
|
||||
this.addForm.seqNo=this.parentProjectPhase.seqNo+"."+(this.parentProjectPhase.childrenCnt+1) |
|
||||
}else{ |
|
||||
this.addForm.seqNo=this.parentProjectPhase.seqNo+"."+1 |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
initSimpleDicts('all',['planType','taskType']).then(res=>{ |
|
||||
this.dicts=res.data.data; |
|
||||
}) |
|
||||
}//end mounted |
|
||||
} |
|
||||
|
|
||||
</script> |
|
||||
|
|
||||
<style scoped> |
|
||||
.padding-20{ |
|
||||
padding-left: 10px; |
|
||||
padding-right: 10px; |
|
||||
padding-top: 20px; |
|
||||
padding-bottom: 20px; |
|
||||
} |
|
||||
</style> |
|
||||
1772
src/views/xm/core/xmPhase/XmPhaseBatch.vue
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,404 +0,0 @@ |
|||||
<template> |
|
||||
<section class="page-container padding"> |
|
||||
|
|
||||
|
|
||||
<el-row class="page-main "> |
|
||||
<el-tabs> |
|
||||
<el-tab-pane label="计划详情"> |
|
||||
<!--新增界面 XmPhase xm_project_phase--> |
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editForm"> |
|
||||
<el-row class="border padding"> |
|
||||
<el-steps :active="parseInt(editForm.phaseStatus)+1" simple finish-status="success" align-center> |
|
||||
<el-step v-for="(item,index) in statusList" @click.native="on_click(item.id)" :title="item.name" :key="index"></el-step> |
|
||||
</el-steps> |
|
||||
</el-row> |
|
||||
<el-row class="border padding"> |
|
||||
<el-form-item label="计划名称" prop="name"> |
|
||||
<el-input v-model="editForm.name" placeholder="计划名称" ></el-input> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="序号" prop="seqNo"> |
|
||||
<el-input v-model="editForm.seqNo" style="width:50%;" placeholder="排序序号,值越小越靠前,如1.0,2.0等"></el-input> |
|
||||
<el-checkbox true-label="1" false-label="0" v-model="editForm.milestone">标记为里程碑</el-checkbox> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="任务类型" prop="taskType"> |
|
||||
<el-select v-model="editForm.taskType"> |
|
||||
<el-option v-for="i in this.dicts.taskType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|
||||
</el-select> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="计划类型" prop="planType"> |
|
||||
<el-select v-model="editForm.planType"> |
|
||||
<el-option v-for="i in this.dicts.planType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|
||||
</el-select> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="备注" prop="remark"> |
|
||||
<el-input type="textarea" rows="4" v-model="editForm.remark" placeholder="备注" ></el-input> |
|
||||
</el-form-item> |
|
||||
|
|
||||
</el-row> |
|
||||
<el-tabs v-model="activeName" class="border padding"> |
|
||||
<el-tab-pane label="工作量及人力成本" name="budgetWorkload"> |
|
||||
<el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-row class="padding">工作量计算方式:<font style="color:red">总工时 = 工作日天数 * 每日工时数 * 人数 </font> </el-row> |
|
||||
<el-row class="padding">金额计算方式: <font style="color:red">总金额 = 总工时 * 工时单价 </font></el-row> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
预计时间:<el-date-picker |
|
||||
v-model="dateRanger" |
|
||||
type="daterange" |
|
||||
align="right" |
|
||||
unlink-panels |
|
||||
range-separator="至" |
|
||||
start-placeholder="计划开始日期" |
|
||||
end-placeholder="计划完成日期" |
|
||||
value-format="yyyy-MM-dd HH:mm:ss" |
|
||||
:default-time="['00:00:00','23:59:59']" |
|
||||
:picker-options="pickerOptions" |
|
||||
></el-date-picker> |
|
||||
预估工期:<el-input style="width:100px;" type="number" v-model="editForm.budgetHours" :precision="2" :step="8" :min="0" placeholder="预计工时"></el-input>小时 |
|
||||
<div class="tips"><font>工时{{autoParams.budgetHours}}小时,工作日{{autoParams.weekday}}天</font></div> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">人员类型</el-col> |
|
||||
<el-col :span="4">人数</el-col> |
|
||||
<el-col :span="4">工作量(人时)</el-col> |
|
||||
<el-col :span="4">单价(元/人时)</el-col> |
|
||||
<el-col :span="8">总价(元)</el-col> |
|
||||
|
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">内购</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="editForm.budgetIuserCnt" :precision="0" :step="1" :min="0" placeholder="内购人数"></el-input> |
|
||||
</el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetIuserWorkload}}人时</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="editForm.budgetIuserPrice" :precision="0" :step="1" :min="0" placeholder="预计内部人时单价"></el-input> </el-col> |
|
||||
<el-col :span="8">{{this.toFixed(autoParams.budgetIuserAt)}}元,{{this.toFixed(autoParams.budgetIuserAt/10000)}} 万元</el-col> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">外购</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="editForm.budgetOuserCnt" :precision="0" :step="1" :min="0" placeholder="外购人数"></el-input> |
|
||||
</el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetOuserWorkload}}人时</el-col> |
|
||||
<el-col :span="4"><el-input style="width:100px;" type="number" v-model="editForm.budgetOuserPrice" :precision="0" :step="1" :min="0" placeholder="预计外购人时单价"></el-input> </el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetOuserAt }} 元 {{autoParams.budgetOuserAt/10000 }}万元</el-col> |
|
||||
|
|
||||
</el-row > |
|
||||
<el-row class="padding-20 border"> |
|
||||
<el-col :span="4">合计</el-col> |
|
||||
<el-col :span="4"> {{autoParams.budgetOuserCnt+autoParams.budgetIuserCnt}} |
|
||||
</el-col> |
|
||||
<el-col :span="4">{{autoParams.budgetOuserWorkload+autoParams.budgetIuserWorkload }}人时,{{ (autoParams.budgetOuserWorkload+autoParams.budgetIuserWorkload)/8/20 }}人月 </el-col> |
|
||||
<el-col :span="4">{{ (parseFloat2(autoParams.budgetOuserPrice) + parseFloat2(autoParams.budgetIuserPrice))/2}}元/人时</el-col> |
|
||||
<el-col :span="8">{{autoParams.budgetTotalCost}} 元,{{(autoParams.budgetTotalCost)/10000}} 万元</el-col> |
|
||||
</el-row> |
|
||||
<el-row class="padding-20 border"> |
|
||||
总计: {{parseFloat2(editForm.budgetIuserAt)+parseFloat2(editForm.budgetOuserAt)+parseFloat2(editForm.budgetNouserAt)}}元 <el-tag>{{this.toFixed(autoParams.budgetTotalCost/10000)}}万元</el-tag> |
|
||||
|
|
||||
</el-row> |
|
||||
</el-row> |
|
||||
</el-tab-pane> |
|
||||
<el-tab-pane v-if="activeName=='budgetWorkload'" label="收起" name=""> |
|
||||
</el-tab-pane> |
|
||||
</el-tabs> |
|
||||
</el-form> |
|
||||
</el-tab-pane> |
|
||||
<el-tab-pane label="计划概览" lazy> |
|
||||
<xm-phase-overview :xm-phase="xmPhase"></xm-phase-overview> |
|
||||
</el-tab-pane> |
|
||||
</el-tabs> |
|
||||
</el-row> |
|
||||
<el-row class="page-bottom"> |
|
||||
<el-button @click.native="handleCancel">取消</el-button> |
|
||||
<el-button v-loading="load.edit" type="primary" @click.native="editSubmit" :disabled="load.edit==true">提交</el-button> |
|
||||
</el-row> |
|
||||
</section> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import util from '@/common/js/util';//全局公共库 |
|
||||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|
||||
import { editXmPhase } from '@/api/xm/core/xmPhase'; |
|
||||
import { mapGetters } from 'vuex' |
|
||||
import XmPhaseOverview from './XmPhaseOverview';//新增界面 |
|
||||
|
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapGetters([ |
|
||||
'userInfo','roles' |
|
||||
]), |
|
||||
|
|
||||
autoParams:function(){ |
|
||||
|
|
||||
|
|
||||
var budgetOuserPrice=this.toFixed(this.editForm.budgetOuserPrice) |
|
||||
var budgetIuserPrice=this.toFixed(this.editForm.budgetIuserPrice) |
|
||||
var budgetOuserCnt=this.toFixed(this.editForm.budgetOuserCnt) |
|
||||
var budgetIuserCnt=this.toFixed(this.editForm.budgetIuserCnt) |
|
||||
var budgetHours=this.toFixed(this.editForm.budgetHours ) |
|
||||
var budgetNouserAt=this.toFixed(this.editForm.budgetNouserAt ) |
|
||||
if(budgetOuserPrice==null || budgetOuserPrice==''){ |
|
||||
budgetOuserPrice=100 |
|
||||
} |
|
||||
if(budgetIuserPrice==null || budgetIuserPrice==''){ |
|
||||
budgetIuserPrice=80 |
|
||||
} |
|
||||
if(budgetOuserCnt==null || budgetOuserCnt==''){ |
|
||||
budgetOuserCnt=0.0 |
|
||||
} |
|
||||
if(budgetIuserCnt==null || budgetIuserCnt==''){ |
|
||||
budgetIuserCnt=0.0 |
|
||||
} |
|
||||
|
|
||||
if(budgetNouserAt==null || budgetNouserAt==''){ |
|
||||
budgetNouserAt=0.0 |
|
||||
} |
|
||||
|
|
||||
if(budgetHours==null || budgetHours==''){ |
|
||||
budgetHours=0.0 |
|
||||
} |
|
||||
var autoParams={ |
|
||||
|
|
||||
} |
|
||||
var weekday=1; |
|
||||
if(this.dateRanger!=null && this.dateRanger.length>=2 ){ |
|
||||
weekday=this.getWeekday(new Date(this.dateRanger[0]),new Date(this.dateRanger[1])); |
|
||||
budgetHours=weekday * 8 |
|
||||
|
|
||||
} |
|
||||
autoParams.weekday=weekday |
|
||||
autoParams.budgetHours=budgetHours |
|
||||
autoParams.budgetOuserPrice=budgetOuserPrice |
|
||||
autoParams.budgetIuserPrice=budgetIuserPrice |
|
||||
autoParams.budgetOuserCnt=budgetOuserCnt |
|
||||
autoParams.budgetIuserCnt=budgetIuserCnt |
|
||||
autoParams.budgetIuserWorkload= budgetIuserCnt*budgetHours |
|
||||
autoParams.budgetOuserWorkload= budgetOuserCnt*budgetHours |
|
||||
autoParams.budgetWorkload= budgetIuserCnt*budgetHours + budgetOuserCnt*budgetHours |
|
||||
autoParams.budgetOuserAt= budgetOuserCnt * budgetHours * budgetOuserPrice |
|
||||
autoParams.budgetIuserAt= budgetIuserCnt * budgetHours * budgetIuserPrice |
|
||||
autoParams.budgetNouserAt= budgetNouserAt |
|
||||
autoParams.budgetTotalCost= autoParams.budgetOuserAt + autoParams.budgetIuserAt + autoParams.budgetNouserAt |
|
||||
return autoParams |
|
||||
}, |
|
||||
}, |
|
||||
props:['xmPhase','visible','parentProjectPhase'], |
|
||||
watch: { |
|
||||
'xmPhase':function( xmPhase ) { |
|
||||
this.editForm = xmPhase; |
|
||||
this.dateRanger=[this.editForm.beginDate,this.editForm.endDate] |
|
||||
}, |
|
||||
'visible':function(visible) { |
|
||||
if(visible==true){ |
|
||||
//从新打开页面时某些数据需要重新加载,可以在这里添加 |
|
||||
} |
|
||||
}, |
|
||||
autoParams:function(autoParams){ |
|
||||
this.fillbudgetHoursToField() |
|
||||
this.fillbudgetAtToField() |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
const beginDate = new Date(); |
|
||||
const endDate = new Date(); |
|
||||
endDate.setTime(beginDate.getTime() + 3600 * 1000 * 24 * 7 * 4); |
|
||||
return { |
|
||||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|
||||
load:{ list: false, add: false, del: false, edit: false },//查询中... |
|
||||
editFormRules: { |
|
||||
id: [ |
|
||||
//{ required: true, message: '计划主键不能为空', trigger: 'blur' } |
|
||||
], |
|
||||
name: [ |
|
||||
{ required: true, message: '计划名称不能为空', trigger: 'blur' } |
|
||||
], |
|
||||
planType: [ |
|
||||
{ required: true, message: '请选择计划类型', trigger: 'blur' } |
|
||||
], |
|
||||
taskType: [ |
|
||||
{ required: true, message: '请选择任务类型', trigger: 'blur' } |
|
||||
], |
|
||||
seqNo: [ |
|
||||
{ required: true, message: '序号不能为空', trigger: 'blur' } |
|
||||
] |
|
||||
}, |
|
||||
oldeditForm:{}, |
|
||||
//新增界面数据 xm_project_phase |
|
||||
editForm: { |
|
||||
id:'',name:'',remark:'',parentPhaseId:'',branchId:'',taskType:'kf',planType:'m1',projectId:'',beginDate:'',endDate:'',budgetHours:'',budgetStaffNu:'',ctime:'',budgetNouserAt:'',budgetIuserAt:'',budgetOuserAt:'',baselineId:'',bizProcInstId:'',bizFlowState:'',budgetWorkload:'',totalActWorkload:'',totalActNouserAt:'',totalActInerUserAt:'',totalActOuserAt:'',seqNo:'1',budgetIuserCnt:'',budgetOuserCnt:'',budgetIuserPrice:80,budgetOuserPrice:100,budgetIuserWorkload:0,budgetOuserWorkload:0,phaseStatus:'',ntype:'0' |
|
||||
}, |
|
||||
dateRanger: [ |
|
||||
], |
|
||||
/**begin 在下面加自定义属性,记得补上面的一个逗号**/ |
|
||||
pickerOptions: util.getPickerOptions('datarange'), |
|
||||
activeName:'', |
|
||||
costVisible:false, |
|
||||
statusList:[ |
|
||||
{id:'0',name:'初始'}, |
|
||||
{id:'1',name:'执行中'}, |
|
||||
{id:'2',name:'完工'}, |
|
||||
{id:'3',name:'关闭'}, |
|
||||
{id:'4',name:'删除中'}, |
|
||||
{id:'5',name:'已删除'}, |
|
||||
{id:'6',name:'暂停'} |
|
||||
] |
|
||||
/**end 在上面加自定义属性**/ |
|
||||
}//end return |
|
||||
},//end data |
|
||||
methods: { |
|
||||
// 取消按钮点击 父组件监听@cancel="editFormVisible=false" 监听 |
|
||||
handleCancel:function(){ |
|
||||
//this.$refs['editForm'].resetFields(); |
|
||||
this.$emit('cancel'); |
|
||||
}, |
|
||||
//新增提交XmPhase xm_project_phase 父组件监听@submit="aftereditSubmit" |
|
||||
editSubmit: function () { |
|
||||
|
|
||||
if ( |
|
||||
this.dateRanger != null && |
|
||||
this.dateRanger.length == 2 |
|
||||
) { |
|
||||
if(this.dateRanger[0]){ |
|
||||
if(this.dateRanger[0].length<=10){ |
|
||||
this.editForm.beginDate = this.dateRanger[0] ; |
|
||||
}else{ |
|
||||
this.editForm.beginDate = this.dateRanger[0] |
|
||||
} |
|
||||
} |
|
||||
if(this.dateRanger[1]){ |
|
||||
if(this.dateRanger[1].length<=10){ |
|
||||
this.editForm.endDate = this.dateRanger[1] ; |
|
||||
}else{ |
|
||||
this.editForm.endDate = this.dateRanger[1] |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
}else{ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "请输入开始日期和结束日期", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
if(!this.editForm.budgetIuserCnt){ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "内购人员数不能为空", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if(!this.editForm.budgetHours){ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "工期不能为空", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
if(!this.editForm.budgetIuserPrice){ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: "内购单价不能为空", type: 'error' }); |
|
||||
return; |
|
||||
} |
|
||||
this.$refs.editForm.validate((valid) => { |
|
||||
if (valid) { |
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => { |
|
||||
this.load.edit=true |
|
||||
let params = Object.assign({}, this.editForm); |
|
||||
if(!params.budgetIuserAt){ |
|
||||
params.budgetIuserAt= this.parseFloat2(params.budgetIuserCnt) * this.parseFloat2(params.budgetIuserPrice) * this.parseFloat2(params.budgetHours) |
|
||||
} |
|
||||
if( !params.budgetOuserAt ){ |
|
||||
params.budgetOuserAt= this.parseFloat2(params.budgetOuserCnt) * this.parseFloat2(params.budgetOuserPrice) * this.parseFloat2(params.budgetHours) |
|
||||
} |
|
||||
params.budgetIuserWorkload= this.parseFloat2(params.budgetIuserCnt) * this.parseFloat2(params.budgetHours) |
|
||||
params.budgetOuserWorkload= this.parseFloat2(params.budgetOuserCnt) * this.parseFloat2(params.budgetHours) |
|
||||
|
|
||||
params.budgetWorkload= this.parseFloat2(params.budgetIuserWorkload) + this.parseFloat2(params.budgetOuserWorkload) |
|
||||
if( !params.budgetStaffNu ){ |
|
||||
|
|
||||
params.budgetStaffNu= this.parseFloat2(params.budgetOuserCnt) + this.parseFloat2(params.budgetIuserCnt) |
|
||||
} |
|
||||
var func=editXmPhase |
|
||||
if(this.editForm.phaseClass=="1"){ |
|
||||
func=editXmPhase |
|
||||
} |
|
||||
func(params).then((res) => { |
|
||||
this.load.edit=false |
|
||||
var tips=res.data.tips; |
|
||||
if(tips.isOk){ |
|
||||
//this.$refs['editForm'].resetFields(); |
|
||||
this.$emit('submit',res.data.data);// @submit="aftereditSubmit" |
|
||||
} |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: tips.msg, type: tips.isOk?'success':'error' }); |
|
||||
}).catch( err => this.load.edit=false); |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
}, |
|
||||
getWeekday(first, last) { |
|
||||
//计算工作日方法:遍历这两个日期区间的每一个日期,获取他的getDay() |
|
||||
|
|
||||
//分别获取first和last的毫秒数(时间戳) |
|
||||
first = first.getTime(); |
|
||||
last = last.getTime(); |
|
||||
|
|
||||
var count = 0; |
|
||||
for (var i = first; i <= last; i += 24 * 3600 * 1000) { |
|
||||
var d = new Date(i); |
|
||||
if (d.getDay() >= 1 && d.getDay() <= 5) { |
|
||||
count++; |
|
||||
} |
|
||||
} |
|
||||
return count; |
|
||||
}, |
|
||||
toFixed(floatValue,num){ |
|
||||
if(floatValue ==null || floatValue=='' || floatValue == undefined){ |
|
||||
return 0; |
|
||||
}else{ |
|
||||
if(!num){ |
|
||||
num=2 |
|
||||
} |
|
||||
return parseFloat(parseFloat(floatValue).toFixed(num)); |
|
||||
} |
|
||||
}, |
|
||||
parseFloat2(floatValue){ |
|
||||
if(floatValue ==null || floatValue=='' || floatValue == undefined){ |
|
||||
return 0; |
|
||||
}else{ |
|
||||
return parseFloat(floatValue); |
|
||||
} |
|
||||
}, |
|
||||
fillToField:function(){ |
|
||||
this.editForm=Object.assign(this.editForm,this.autoParams); |
|
||||
}, |
|
||||
fillbudgetHoursToField:function(){ |
|
||||
this.editForm.budgetHours=this.toFixed(this.autoParams.budgetHours) |
|
||||
}, |
|
||||
|
|
||||
fillbudgetAtToField:function(){ |
|
||||
this.editForm.budgetNouserAt=this.toFixed(this.autoParams.budgetNouserAt) |
|
||||
this.editForm.budgetOuserAt=this.toFixed(this.autoParams.budgetOuserAt ) |
|
||||
this.editForm.budgetIuserAt=this.toFixed(this.autoParams.budgetIuserAt ) |
|
||||
this.editForm.budgetTotalCost=this.toFixed(this.autoParams.budgetTotalCost) |
|
||||
|
|
||||
}, |
|
||||
on_click(status){ |
|
||||
this.editForm.phaseStatus=status; |
|
||||
} |
|
||||
/**end 在上面加自定义方法**/ |
|
||||
|
|
||||
},//end method |
|
||||
components: { |
|
||||
XmPhaseOverview, |
|
||||
//在下面添加其它组件 'xm-phase-edit':XmPhaseEdit |
|
||||
}, |
|
||||
mounted() { |
|
||||
this.editForm=Object.assign(this.editForm, this.xmPhase); |
|
||||
/**在下面写其它函数***/ |
|
||||
this.dateRanger=[this.editForm.beginDate,this.editForm.endDate] |
|
||||
initSimpleDicts('all',['planType','taskType']).then(res=>{ |
|
||||
this.dicts=res.data.data; |
|
||||
}) |
|
||||
}//end mounted |
|
||||
} |
|
||||
|
|
||||
</script> |
|
||||
|
|
||||
<style scoped> |
|
||||
.padding-20{ |
|
||||
padding-left: 10px; |
|
||||
padding-right: 10px; |
|
||||
padding-top: 20px; |
|
||||
padding-bottom: 20px; |
|
||||
} |
|
||||
</style> |
|
||||
1290
src/views/xm/core/xmPhase/XmPhaseForProduct.vue
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1328
src/views/xm/core/xmPhase/XmPhaseMng.vue
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,576 +0,0 @@ |
|||||
<template> |
|
||||
<section> |
|
||||
<el-row class="page-main " style="overflow-x: hidden;"> |
|
||||
<el-row style="margin-bottom:10px"> |
|
||||
<el-card class="box-card" style="padding:0px ;height:100px"> |
|
||||
<div> |
|
||||
<el-row style="padding:10px"> |
|
||||
<el-steps :active="this.xmPhase.phaseStatus" finish-status="success" align-center> |
|
||||
<el-step title="初始"></el-step> |
|
||||
<el-step title="执行中"></el-step> |
|
||||
<el-step title="完工"></el-step> |
|
||||
<el-step title="关闭"></el-step> |
|
||||
<el-step title="删除中"></el-step> |
|
||||
<el-step title="已删除"></el-step> |
|
||||
<el-step title="暂停"></el-step> |
|
||||
</el-steps> |
|
||||
</el-row> |
|
||||
</div> |
|
||||
</el-card> |
|
||||
</el-row> |
|
||||
<el-row :gutter="10" style="margin-bottom:10px"> |
|
||||
<el-col :span="12" > |
|
||||
<el-card class="box-card" style="padding:0px ;height:425px"> |
|
||||
<div slot="header" class="clearfix"> |
|
||||
<span>计划信息</span> |
|
||||
</div> |
|
||||
<el-row style="margin-bottom:18px"> |
|
||||
<el-row> |
|
||||
<span v-text="this.xmPhase.mngUsername"></span> |
|
||||
</el-row> |
|
||||
<el-row> |
|
||||
<span>计划管理员</span> |
|
||||
</el-row> |
|
||||
</el-row> |
|
||||
<el-row style="margin-bottom:18px"> |
|
||||
<el-col :span="8" @click=""> |
|
||||
<div class="item"> |
|
||||
<div class="icon" style="background-color: rgb(79, 140, 255);"> |
|
||||
<i class="el-icon-right"></i> |
|
||||
</div> |
|
||||
<div class="info"> |
|
||||
<div v-text="this.xmPhase.taskCnt"></div> |
|
||||
<div class="title">总任务量</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
<el-col :span="8"> |
|
||||
<div class="item"> |
|
||||
<div class="icon" style="background-color: rgb(255, 153, 51);"> |
|
||||
<i class="el-icon-loading"></i> |
|
||||
</div> |
|
||||
<div class="info"> |
|
||||
<div v-text="notStart"> |
|
||||
</div> |
|
||||
<div class="title">待完成</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
<el-col :span="8"> |
|
||||
<div class="item"> |
|
||||
<div class="icon" style="background-color: rgb(0, 153, 51);"> |
|
||||
<i class="el-icon-check"></i> |
|
||||
</div> |
|
||||
<div class="info"> |
|
||||
<div v-text="this.xmPhase.taskFinishCnt" > |
|
||||
</div> |
|
||||
<div class="title">已完成</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
</el-row> |
|
||||
<el-row style="margin-bottom:18px"> |
|
||||
<div class="item"> |
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);"> |
|
||||
<i class="el-icon-date"></i> |
|
||||
</div> |
|
||||
<div class="info"> |
|
||||
<div v-text="phaseBeginDate+'~'+phaseEndDate"> |
|
||||
</div> |
|
||||
<div class="title">计划周期</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-row> |
|
||||
<el-row style="margin-bottom:18px"> |
|
||||
<div class="item"> |
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);"> |
|
||||
<i class="el-icon-star-off"></i> |
|
||||
</div> |
|
||||
<div class="info"> |
|
||||
<div class="title"> 创建时间: {{this.phaseCreateDate}}</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-row> |
|
||||
<el-row style="margin-bottom:18px"> |
|
||||
<div class="item"> |
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);"> |
|
||||
<i class="el-icon-refresh"></i> |
|
||||
</div> |
|
||||
<div class="info"> |
|
||||
<div class="title"> 关联迭代数: {{(this.xmPhase.iterationCnt)}} </div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-row> |
|
||||
<el-row style="margin-bottom:18px"> |
|
||||
<div class="item"> |
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);"> |
|
||||
<i class="el-icon-alarm-clock"></i> |
|
||||
</div> |
|
||||
<div> |
|
||||
<div class="progress-item"> |
|
||||
<el-progress :percentage="taskProgress"></el-progress> |
|
||||
<div class="title">任务进度</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-row> |
|
||||
</el-card> |
|
||||
</el-col> |
|
||||
<el-col :span="12" > |
|
||||
<el-card class="box-card" style="padding:0px ;height:425px"> |
|
||||
<div slot="header" class="clearfix"> |
|
||||
<span>计划工时</span> |
|
||||
</div> |
|
||||
<div> |
|
||||
<el-row style="padding:25px;"> |
|
||||
<div class="item"> |
|
||||
<el-col :span="8"> |
|
||||
<div> |
|
||||
<div style="text-align:center;"> |
|
||||
<span style="font-size:24px;" v-text="this.xmPhase.budgetWorkload"></span> |
|
||||
<span style="font-size:5px;">h</span> |
|
||||
</div> |
|
||||
<div style="text-align:center;font-size:5px;">预估工时</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
<el-col :span="8"> |
|
||||
<div> |
|
||||
<div style="text-align:center;"> |
|
||||
<span style="font-size:24px;" v-text="this.xmPhase.actWorkload"></span> |
|
||||
<span style="font-size:5px;">h</span> |
|
||||
</div> |
|
||||
<div style="text-align:center;font-size:5px;">登记工时</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
<el-col :span="8"> |
|
||||
<div> |
|
||||
<div style="text-align:center;"> |
|
||||
<span style="font-size:24px;" v-text="workloadProgress"></span> |
|
||||
<span style="font-size:5px;">%</span> |
|
||||
</div> |
|
||||
<div style="text-align:center;font-size:5px;">工时进度</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
</div> |
|
||||
</el-row> |
|
||||
<el-row style="padding:25px;"> |
|
||||
<div class="item"> |
|
||||
<el-col :span="8"> |
|
||||
<div> |
|
||||
<div style="text-align:center;"> |
|
||||
<span style="font-size:24px;" v-text="remainWorkload"></span> |
|
||||
<span style="font-size:5px;">h</span> |
|
||||
</div> |
|
||||
<div style="text-align:center;font-size:5px;">剩余工时</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
<el-col :span="8"> |
|
||||
<div> |
|
||||
<div style="text-align:center;"> |
|
||||
<span style="font-size:24px;" v-text="deviation"></span> |
|
||||
<span style="font-size:5px;">h</span> |
|
||||
</div> |
|
||||
<div style="text-align:center;font-size:5px;">预估偏差</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
<el-col :span="8"> |
|
||||
<div> |
|
||||
<div style="text-align:center;"> |
|
||||
<span style="font-size:24px;" v-text="deviationRate"></span> |
|
||||
<span style="font-size:5px;">%</span> |
|
||||
</div> |
|
||||
<div style="text-align:center;font-size:5px;">预估偏差率</div> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
</div> |
|
||||
</el-row> |
|
||||
<el-row> |
|
||||
<span style="margin-left:20px;">项目预计进度</span> |
|
||||
<el-progress style="width: 90%;margin-left:20px;margin-top: 10px;margin-bottom: 20px;" :text-inside="true" :stroke-width="24" :percentage="planProgress"></el-progress> |
|
||||
</el-row> |
|
||||
<el-row> |
|
||||
<span style="margin-left:20px;">项目实际进度</span> |
|
||||
<el-progress style="width: 90%;margin-left:20px;margin-top: 10px;" :text-inside="true" :stroke-width="24" :percentage="realProgress"></el-progress> |
|
||||
</el-row> |
|
||||
</div> |
|
||||
</el-card> |
|
||||
</el-col> |
|
||||
</el-row> |
|
||||
<el-row :gutter="10" style="margin-bottom:10px"> |
|
||||
<el-col :span="12" > |
|
||||
<el-card class="box-card" style="height:425px"> |
|
||||
<div slot="header" class="clearfix"> |
|
||||
<span>总预算情况</span> |
|
||||
</div> |
|
||||
<div style="'100%'"> |
|
||||
<div id="costPieChart" :style="{width: '100%', height: '300px'}"></div> |
|
||||
</div> |
|
||||
</el-card> |
|
||||
</el-col> |
|
||||
<el-col :span="12" > |
|
||||
<el-card class="box-card" style="height:425px"> |
|
||||
<div slot="header" class="clearfix"> |
|
||||
<span>工作量分布</span> |
|
||||
</div> |
|
||||
<div> |
|
||||
<div id="workloadPie" :style="{width: '100%', height: '300px'}"></div> |
|
||||
</div> |
|
||||
</el-card> |
|
||||
</el-col> |
|
||||
</el-row> |
|
||||
</el-row> |
|
||||
</section> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import util from '@/common/js/util';//全局公共库 |
|
||||
//import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|
||||
import { mapGetters } from 'vuex' |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapGetters(['userInfo','roles']), |
|
||||
notStart: function() { |
|
||||
return this.xmPhase.taskCnt-this.xmPhase.taskFinishCnt; |
|
||||
}, |
|
||||
taskProgress: function (){ |
|
||||
if(this.xmPhase.actRate){ |
|
||||
return this.xmPhase.actRate; |
|
||||
}else{ |
|
||||
return 0; |
|
||||
} |
|
||||
}, |
|
||||
phaseBeginDate: function (){ |
|
||||
if(this.xmPhase.beginDate){ |
|
||||
return this.xmPhase.beginDate.substring(0,10); |
|
||||
} else{ |
|
||||
return '暂无'; |
|
||||
} |
|
||||
}, |
|
||||
phaseEndDate: function (){ |
|
||||
if(this.xmPhase.endDate){ |
|
||||
return this.xmPhase.endDate.substring(0,10); |
|
||||
} else{ |
|
||||
return '暂无'; |
|
||||
} |
|
||||
}, |
|
||||
phaseCreateDate: function (){ |
|
||||
if(this.xmPhase.ctime){ |
|
||||
return this.xmPhase.ctime.substring(0,10); |
|
||||
} else{ |
|
||||
return '暂无'; |
|
||||
} |
|
||||
}, |
|
||||
workloadProgress:function (){ |
|
||||
return Math.round(this.xmPhase.actWorkload/this.xmPhase.budgetWorkload*100); |
|
||||
}, |
|
||||
deviation:function (){ |
|
||||
let now = new Date(); |
|
||||
let startTime = new Date(this.xmPhase.beginDate); |
|
||||
let endTime = new Date(this.xmPhase.endDate); |
|
||||
if(now<=endTime){ |
|
||||
let allDays=endTime-startTime; |
|
||||
return this.xmPhase.budgetWorkload - Math.round((now-startTime)/allDays*this.xmPhase.budgetWorkload) |
|
||||
}else{ |
|
||||
return this.xmPhase.actWorkload - this.xmPhase.budgetWorkload; |
|
||||
} |
|
||||
}, |
|
||||
deviationRate:function (){ |
|
||||
return Math.round(this.deviation/this.xmPhase.budgetWorkload*100); |
|
||||
}, |
|
||||
remainWorkload:function (){ |
|
||||
return this.xmPhase.budgetWorkload - this.xmPhase.actWorkload; |
|
||||
}, |
|
||||
planProgress:function (){ |
|
||||
let now = new Date(); |
|
||||
let startTime = new Date(this.xmPhase.beginDate); |
|
||||
let endTime = new Date(this.xmPhase.endDate); |
|
||||
if(now<=endTime){ |
|
||||
let allDays=endTime-startTime; |
|
||||
return Math.round((now-startTime)/allDays*100) |
|
||||
}else{ |
|
||||
return 100; |
|
||||
} |
|
||||
}, |
|
||||
realProgress:function (){ |
|
||||
if(this.xmPhase.actWorkload < this.xmPhase.budgetWorkload){ |
|
||||
return Math.round(this.xmPhase.actWorkload/this.xmPhase.budgetWorkload*100) |
|
||||
}else{ |
|
||||
return 100; |
|
||||
} |
|
||||
}, |
|
||||
xmPhaseCpd(){ |
|
||||
return this.xmPhase |
|
||||
}, |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
props:['xmPhase'], |
|
||||
watch:{ |
|
||||
xmPhaseCpd:function(){ |
|
||||
this.drawCostPie(); |
|
||||
this.drawWorkloadPie(); |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
methods:{ |
|
||||
drawCostPie() { |
|
||||
let costPieChart = this.$echarts.init(document.getElementById("costPieChart")); |
|
||||
let option = { |
|
||||
tooltip: { |
|
||||
trigger: 'item', |
|
||||
formatter: '{b} : {c} ({d}%)' |
|
||||
}, |
|
||||
legend: { |
|
||||
orient: 'vertical', |
|
||||
left: 'left', |
|
||||
}, |
|
||||
series: [ |
|
||||
{ |
|
||||
center:['55%','40%'],//饼图位置 |
|
||||
type: 'pie', |
|
||||
radius: '50%',//饼图半径大小 |
|
||||
label:{ //饼图图形上的文本标签 |
|
||||
normal:{ |
|
||||
show:true, |
|
||||
position:'outer', //标签的位置:外部 |
|
||||
textStyle : { |
|
||||
fontWeight : 100 , |
|
||||
fontSize: document.body.clientWidth / 120, //标签字体大小 |
|
||||
color: "#000000" |
|
||||
}, |
|
||||
formatter:'{b}\n{c}({d}%)',//b:name,c:value,d:占比 |
|
||||
alignTo:'edge', |
|
||||
margin:10 |
|
||||
} |
|
||||
}, |
|
||||
data: [ |
|
||||
{value: this.xmPhase.budgetNouserAt, |
|
||||
itemStyle: { |
|
||||
normal:{ |
|
||||
color: '#5470C6' |
|
||||
} |
|
||||
}, |
|
||||
name: '非人力'}, |
|
||||
{value: this.xmPhase.budgetIuserAt, |
|
||||
itemStyle: { |
|
||||
normal:{ |
|
||||
color: '#73C0DE' |
|
||||
} |
|
||||
}, |
|
||||
name: '内部人力'}, |
|
||||
{value: this.xmPhase.budgetOuserAt, |
|
||||
itemStyle: { |
|
||||
normal:{ |
|
||||
color: '#99CCFF' |
|
||||
} |
|
||||
}, |
|
||||
name: '外购人力'}, |
|
||||
], |
|
||||
emphasis: { |
|
||||
itemStyle: { |
|
||||
shadowBlur: 10, |
|
||||
shadowOffsetX: 0, |
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
] |
|
||||
}; |
|
||||
// 绘制图表 |
|
||||
costPieChart.setOption(option); |
|
||||
}, |
|
||||
drawWorkloadPie() { |
|
||||
let workloadPie = this.$echarts.init(document.getElementById("workloadPie")); |
|
||||
let option = { |
|
||||
tooltip: { |
|
||||
trigger: 'item', |
|
||||
formatter: '{b} : {c} ({d}%)' |
|
||||
}, |
|
||||
legend: { |
|
||||
orient: 'vertical', |
|
||||
left: 'left', |
|
||||
}, |
|
||||
series: [ |
|
||||
{ |
|
||||
center:['55%','40%'],//饼图位置 |
|
||||
type: 'pie', |
|
||||
radius: '50%',//饼图半径大小 |
|
||||
label:{ //饼图图形上的文本标签 |
|
||||
normal:{ |
|
||||
show:true, |
|
||||
position:'outer', //标签的位置:外部 |
|
||||
textStyle : { |
|
||||
fontWeight : 100 , |
|
||||
fontSize: document.body.clientWidth / 120, //标签字体大小 |
|
||||
color: "#000000" |
|
||||
}, |
|
||||
formatter:'{b}\n{c}({d}%)',//b:name,c:value,d:占比 |
|
||||
alignTo:'edge', |
|
||||
margin:10 |
|
||||
} |
|
||||
}, |
|
||||
data: [ |
|
||||
{value: this.xmPhase.budgetIuserWorkload, |
|
||||
itemStyle: { |
|
||||
normal:{ |
|
||||
color: '#5470C6' |
|
||||
} |
|
||||
}, |
|
||||
name: '内部人力'}, |
|
||||
{value: this.xmPhase.budgetOuserWorkload, |
|
||||
itemStyle: { |
|
||||
normal:{ |
|
||||
color: '#73C0DE' |
|
||||
} |
|
||||
}, |
|
||||
name: '外购人力'}, |
|
||||
], |
|
||||
emphasis: { |
|
||||
itemStyle: { |
|
||||
shadowBlur: 10, |
|
||||
shadowOffsetX: 0, |
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
] |
|
||||
}; |
|
||||
// 绘制图表 |
|
||||
workloadPie.setOption(option); |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
mounted() { |
|
||||
this.$nextTick(() => { |
|
||||
}); |
|
||||
this.drawCostPie(); |
|
||||
this.drawWorkloadPie(); |
|
||||
}, |
|
||||
|
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style scoped lang="scss"> |
|
||||
.container { |
|
||||
margin: 10px; |
|
||||
} |
|
||||
|
|
||||
.header { |
|
||||
display: flex; |
|
||||
justify-content: flex-start; |
|
||||
padding: 10px; |
|
||||
|
|
||||
span { |
|
||||
padding-right: 15px; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.col { |
|
||||
margin-bottom: 20px; |
|
||||
} |
|
||||
|
|
||||
.icon { |
|
||||
color: #fff; |
|
||||
height: 30px; |
|
||||
width: 30px; |
|
||||
border-radius: 15px; |
|
||||
text-align: center; |
|
||||
line-height: 30px; |
|
||||
font-size: 20px; |
|
||||
display: inline-block; |
|
||||
margin-right: 5px; |
|
||||
} |
|
||||
|
|
||||
.icon2 { |
|
||||
color: #000000; |
|
||||
height: 30px; |
|
||||
width: 30px; |
|
||||
border-radius: 15px; |
|
||||
text-align: center; |
|
||||
line-height: 30px; |
|
||||
font-size: 20px; |
|
||||
display: inline-block; |
|
||||
margin-right: 5px; |
|
||||
margin-left: 5px; |
|
||||
} |
|
||||
|
|
||||
.item { |
|
||||
display: flex; |
|
||||
justify-content: flex-start; |
|
||||
position: relative; |
|
||||
.progress-item{ |
|
||||
position:absolute; width:80%; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.card-font { |
|
||||
color: #000000; |
|
||||
font-size: 12px; |
|
||||
|
|
||||
.el-col { |
|
||||
margin-bottom: 20px; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.calendar-header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
|
|
||||
.cal-header-boxs { |
|
||||
flex: 1; |
|
||||
display: flex; |
|
||||
justify-content: flex-end; |
|
||||
|
|
||||
.cal-header-box { |
|
||||
padding: 5px; |
|
||||
height: 45px; |
|
||||
margin-left: 10px; |
|
||||
} |
|
||||
|
|
||||
.box-icon { |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.box-info { |
|
||||
text-align: center; |
|
||||
font-size: 12px; |
|
||||
color: #000000; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.el-tag:hover { |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.value { |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.reference { |
|
||||
margin-top: 10px; |
|
||||
font-size: 12px; |
|
||||
} |
|
||||
|
|
||||
.click { |
|
||||
background: #e9f7ff; |
|
||||
} |
|
||||
|
|
||||
.calendar-box { |
|
||||
display: flex; |
|
||||
justify-content: flex-start; |
|
||||
} |
|
||||
</style> |
|
||||
|
|
||||
<style> |
|
||||
.app-container{ |
|
||||
padding: 20px; |
|
||||
padding-bottom: 0; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,484 +0,0 @@ |
|||||
<template> |
|
||||
<section> |
|
||||
<el-row> |
|
||||
<el-table lazy :load="loadXmPhaseLazy" :height="tableHeight" ref="selectPhaseTable" :data="projectPhaseTreeData" :show-summary="false" row-key="id" :tree-props="{children: 'children', hasChildren: 'childrenCnt'}" @sort-change="sortChange" highlight-current-row v-loading="load.list" border @selection-change="selsChange" @row-click="rowClick" style="width: 100%;"> |
|
||||
<el-table-column prop="name" label="计划名称" show-overflow-tooltip> |
|
||||
<template slot="header" slot-scope="scope"> |
|
||||
<span>计划 <el-tag type="warning" v-if="editForm.id" closable @close="clearSelectPhase()"> <font class="hidden-md-and-down">{{editForm.name}}</font><font class="hidden-lg-and-up" style="font-size:2px;">{{editForm.name}}</font></el-tag></span> |
|
||||
</template> |
|
||||
<template slot-scope="scope"> |
|
||||
<span class="vlink">{{scope.row.seqNo}} <el-tooltip v-if="scope.row.milestone=='1'" content="里程碑"><i class="el-icon-star-on"></i></el-tooltip>{{scope.row.name}} |
|
||||
<font :color="scope.row.actRate>=100?'green':'#FF8C00'"> {{ (scope.row.actRate!=null?scope.row.actRate:0)+'%'}} </font> |
|
||||
</span> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
</el-table> |
|
||||
<el-pagination layout=" total, prev, next" @current-change="handleCurrentChange" @size-change="handleSizeChange" :page-sizes="[10,20, 50, 100, 500]" :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :total="pageInfo.total" style="float:right;"></el-pagination> |
|
||||
|
|
||||
</el-row> |
|
||||
</section> |
|
||||
</template> |
|
||||
<script> |
|
||||
import util from '@/common/js/util';//全局公共库 |
|
||||
//import Sticky from '@/components/Sticky' // 粘性header组件 |
|
||||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|
||||
import { listXmPhase } from '@/api/xm/core/xmPhase'; |
|
||||
|
|
||||
import {sn} from '@/common/js/sequence' |
|
||||
import { mapGetters } from 'vuex' |
|
||||
|
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapGetters([ |
|
||||
'userInfo','roles' |
|
||||
]), |
|
||||
projectPhaseTreeData() { |
|
||||
let xmPhases = this.xmPhases |
|
||||
|
|
||||
var projectPhaseTreeData = this.translateDataToTree(xmPhases); |
|
||||
|
|
||||
return projectPhaseTreeData; |
|
||||
}, |
|
||||
|
|
||||
}, |
|
||||
props:['selProject','xmIteration'], |
|
||||
watch:{ |
|
||||
selProject:function(selProject,old){ |
|
||||
|
|
||||
if(!selProject){ |
|
||||
this.xmPhases=[] |
|
||||
}else{ |
|
||||
if( ( !old && selProject.id) || (old && selProject.id!=old.id)){ |
|
||||
|
|
||||
this.searchXmPhases(); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
xmIteration(){ |
|
||||
this.searchXmPhases(); |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
|
|
||||
return { |
|
||||
filters: { |
|
||||
key: '' |
|
||||
}, |
|
||||
xmPhases: [],//查询结果 |
|
||||
pageInfo:{//分页数据 |
|
||||
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
|
||||
pageSize:50,//每页数据 |
|
||||
count:false,//是否需要重新计算总记录数 |
|
||||
pageNum:1,//当前页码、从1开始计算 |
|
||||
orderFields:[],//排序列 如 ['sex','student_id'],必须为数据库字段 |
|
||||
orderDirs:[]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
|
||||
}, |
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|
||||
sels: [],//列表选中数据 |
|
||||
dicts:{ |
|
||||
xmPhaseStatus:[], |
|
||||
},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|
||||
|
|
||||
addFormVisible: false,//新增xmPhase界面是否显示 |
|
||||
//新增xmPhase界面初始化数据 |
|
||||
addForm: { |
|
||||
id:'',name:'',remark:'',parentPhaseId:'',branchId:'',taskType:'kf',planType:'m1',projectId:'',beginDate:'',endDate:'',budgetHours:'',budgetStaffNu:'',ctime:'',budgetNouserAt:'',budgetIuserAt:'',budgetOuserAt:'',baselineId:'',bizProcInstId:'',bizFlowState:'',budgetIuserCnt:'',budgetOuserCnt:'',seqNo:'',budgetIuserPrice:80,budgetOuserPrice:100,budgetIuserWorkload:0,budgetOuserWorkload:0 |
|
||||
}, |
|
||||
|
|
||||
editFormVisible: false,//编辑界面是否显示 |
|
||||
//编辑xmPhase界面初始化数据 |
|
||||
editForm: { |
|
||||
id:'',name:'',remark:'',parentPhaseId:'',branchId:'',projectId:'',beginDate:'',endDate:'',budgetHours:'',budgetStaffNu:'',ctime:'',budgetNouserAt:'',budgetIuserAt:'',budgetOuserAt:'',baselineId:'',bizProcInstId:'',bizFlowState:'',budgetIuserCnt:'',budgetOuserCnt:'',seqNo:'',budgetIuserPrice:80,budgetOuserPrice:100,budgetIuserWorkload:0,budgetOuserWorkload:0 |
|
||||
}, |
|
||||
|
|
||||
editFormInit: { |
|
||||
id:'',name:'',remark:'',parentPhaseId:'',branchId:'',taskType:'kf',planType:'m1',projectId:'',beginDate:'',endDate:'',budgetHours:'',budgetStaffNu:'',ctime:'',budgetNouserAt:'',budgetIuserAt:'',budgetOuserAt:'',baselineId:'',bizProcInstId:'',bizFlowState:'',budgetIuserCnt:'',budgetOuserCnt:'',seqNo:'',budgetIuserPrice:80,budgetOuserPrice:100,budgetIuserWorkload:0,budgetOuserWorkload:0 |
|
||||
}, |
|
||||
parentProjectPhase:null, |
|
||||
/**begin 自定义属性请在下面加 请加备注**/ |
|
||||
phaseTemplateVisible:false, |
|
||||
xmRecordVisible:false, |
|
||||
valueChangeRows:[], |
|
||||
batchEditVisible:false, |
|
||||
menuVisible:false,//由需求自动创建计划 |
|
||||
pickerOptions: util.getPickerOptions('date'), |
|
||||
gstcVisible:false, |
|
||||
tableHeight:300, |
|
||||
ganrrColumns: { |
|
||||
children: 'children', |
|
||||
name: 'name', |
|
||||
id: 'id', |
|
||||
pid: 'parentPhaseId', |
|
||||
startDate: 'beginDate', |
|
||||
endDate: 'endDate', |
|
||||
}, |
|
||||
/**end 自定义属性请在上面加 请加备注**/ |
|
||||
} |
|
||||
},//end data |
|
||||
methods: { |
|
||||
handleSizeChange(pageSize) { |
|
||||
this.pageInfo.pageSize=pageSize; |
|
||||
this.getXmPhases(); |
|
||||
}, |
|
||||
handleCurrentChange(pageNum) { |
|
||||
this.pageInfo.pageNum = pageNum; |
|
||||
this.getXmPhases(); |
|
||||
}, |
|
||||
// 表格排序 obj.order=ascending/descending,需转化为 asc/desc ; obj.prop=表格中的排序字段,字段驼峰命名 |
|
||||
sortChange( obj ){ |
|
||||
var dir='asc'; |
|
||||
if(obj.order=='ascending'){ |
|
||||
dir='asc' |
|
||||
}else{ |
|
||||
dir='desc'; |
|
||||
} |
|
||||
if(obj.prop=='xxx'){ |
|
||||
this.pageInfo.orderFields=['xxx']; |
|
||||
this.pageInfo.orderDirs=[dir]; |
|
||||
} |
|
||||
this.getXmPhases(); |
|
||||
}, |
|
||||
searchXmPhases(){ |
|
||||
this.pageInfo.count=true; |
|
||||
this.getXmPhases(); |
|
||||
}, |
|
||||
|
|
||||
getParams(params){ |
|
||||
|
|
||||
if(this.filters.key){ |
|
||||
params.key='%'+this.filters.key+'%' |
|
||||
} |
|
||||
if(this.selProject!=null && this.selProject!=undefined){ |
|
||||
params.projectId=this.selProject.id |
|
||||
|
|
||||
} |
|
||||
if(this.xmIteration){ |
|
||||
params.iterationId=this.xmIteration.id |
|
||||
} |
|
||||
if(this.xmProduct){ |
|
||||
params.productId=this.xmProduct.id |
|
||||
} |
|
||||
|
|
||||
if(this.filters.milestone){ |
|
||||
params.milestone=this.filters.milestone |
|
||||
} |
|
||||
|
|
||||
if(this.filters.isKeyPath){ |
|
||||
params.isKeyPath=this.filters.isKeyPath |
|
||||
} |
|
||||
|
|
||||
if(this.filters.phaseStatus){ |
|
||||
params.phaseStatus=this.filters.phaseStatus |
|
||||
} |
|
||||
|
|
||||
if(!(params.isKeyPath||params.milestone||params.productId||params.iterationId||params.phaseStatus)){ |
|
||||
params.isTop="1" |
|
||||
} |
|
||||
return params; |
|
||||
}, |
|
||||
loadXmPhaseLazy(row, treeNode, resolve) { |
|
||||
if(row.children&&row.children.length>0){ |
|
||||
resolve(row.children) |
|
||||
}else{ |
|
||||
var params={parentPhaseId:row.id} |
|
||||
params=this.getParams(params); |
|
||||
params.isTop="" |
|
||||
this.load.list = true; |
|
||||
var func=listXmPhase |
|
||||
func(params).then(res=>{ |
|
||||
this.load.list = false |
|
||||
var tips = res.data.tips; |
|
||||
if(tips.isOk){ |
|
||||
resolve(res.data.data) |
|
||||
}else{ |
|
||||
resolve([]) |
|
||||
} |
|
||||
}).catch( err => this.load.list = false ); |
|
||||
} |
|
||||
|
|
||||
}, |
|
||||
//获取列表 XmPhase xm_project_phase |
|
||||
getXmPhases() { |
|
||||
let params = { |
|
||||
pageSize: this.pageInfo.pageSize, |
|
||||
pageNum: this.pageInfo.pageNum, |
|
||||
total: this.pageInfo.total, |
|
||||
count:this.pageInfo.count |
|
||||
}; |
|
||||
if(this.pageInfo.orderFields!=null && this.pageInfo.orderFields.length>0){ |
|
||||
let orderBys=[]; |
|
||||
for(var i=0;i<this.pageInfo.orderFields.length;i++){ |
|
||||
orderBys.push(this.pageInfo.orderFields[i]+" "+this.pageInfo.orderDirs[i]) |
|
||||
} |
|
||||
params.orderBy= orderBys.join(",") |
|
||||
} |
|
||||
params=this.getParams(params) |
|
||||
params.withParents="1" |
|
||||
this.load.list = true; |
|
||||
listXmPhase(params).then((res) => { |
|
||||
var tips=res.data.tips; |
|
||||
if(tips.isOk){ |
|
||||
this.pageInfo.total = res.data.total; |
|
||||
this.pageInfo.count=false; |
|
||||
this.xmPhases = res.data.data; |
|
||||
}else{ |
|
||||
this.$notify({position:'bottom-left',showClose:true,message: tips.msg, type: 'error' }); |
|
||||
} |
|
||||
this.load.list = false; |
|
||||
}).catch( err => this.load.list = false ); |
|
||||
}, |
|
||||
|
|
||||
//选择行xmPhase |
|
||||
selsChange: function (sels) { |
|
||||
this.sels = sels; |
|
||||
}, |
|
||||
|
|
||||
clearSelectPhase(){ |
|
||||
this.editForm=this.editFormInit |
|
||||
this.$emit('clear-select',null );// @row-click="rowClick" |
|
||||
}, |
|
||||
rowClick: function(row, event, column){ |
|
||||
|
|
||||
var myrow=JSON.parse(JSON.stringify(row)) |
|
||||
myrow.children=[]; |
|
||||
this.parentProjectPhase=myrow |
|
||||
this.editForm=row; |
|
||||
this.$emit('row-click',myrow, event, column);// @row-click="rowClick" |
|
||||
}, |
|
||||
/**begin 自定义函数请在下面加**/ |
|
||||
translateDataToTree(data2) { |
|
||||
var data=JSON.parse(JSON.stringify(data2)); |
|
||||
let parents = data.filter(value =>{ |
|
||||
//如果我的上级为空,则我是最上级 |
|
||||
if(value.parentPhaseId == 'undefined' || value.parentPhaseId == null || value.parentPhaseId == ''){ |
|
||||
return true; |
|
||||
|
|
||||
//如果我的上级不在列表中,我作为最上级 |
|
||||
}else if(data.some(i=>value.parentPhaseId==i.id)){ |
|
||||
return false; |
|
||||
}else { |
|
||||
return true |
|
||||
} |
|
||||
|
|
||||
}) |
|
||||
let children = data.filter(value =>{ |
|
||||
if(data.some(i=>value.parentPhaseId==i.id)){ |
|
||||
return true; |
|
||||
}else{ |
|
||||
return false; |
|
||||
} |
|
||||
}) |
|
||||
let translator = (parents, children) => { |
|
||||
parents.forEach((parent) => { |
|
||||
children.forEach((current, index) => { |
|
||||
if (current.parentPhaseId === parent.id) { |
|
||||
let temp = JSON.parse(JSON.stringify(children)) |
|
||||
temp.splice(index, 1) |
|
||||
translator([current], temp) |
|
||||
typeof parent.children !== 'undefined' ? parent.children.push(current) : parent.children = [current] |
|
||||
} |
|
||||
} |
|
||||
) |
|
||||
} |
|
||||
) |
|
||||
} |
|
||||
|
|
||||
translator(parents, children) |
|
||||
|
|
||||
return parents |
|
||||
}, |
|
||||
|
|
||||
getFloatValue(value,digit){ |
|
||||
if(value==null || value=='' || value==undefined){ |
|
||||
value=0; |
|
||||
return value; |
|
||||
} |
|
||||
if(!digit){ |
|
||||
digit=2 |
|
||||
} |
|
||||
if(typeof( value )=='string'){ |
|
||||
return parseFloat(value); |
|
||||
}else{ |
|
||||
return value |
|
||||
} |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
formatDate(dateStr){ |
|
||||
if(dateStr==null || dateStr==""){ |
|
||||
return ""; |
|
||||
}else{ |
|
||||
return dateStr.substr(0,10); |
|
||||
} |
|
||||
}, |
|
||||
calcTaskStateByTime(startTime,endTime,actRate,phaseStatus){ |
|
||||
if(startTime==null || startTime=="" || endTime==null || endTime ==""){ |
|
||||
return {remark:"未配置日期",status:'warning'} |
|
||||
} |
|
||||
var curDate=new Date(); |
|
||||
var start=new Date(startTime); |
|
||||
var end=new Date(endTime); |
|
||||
if(this.getDaysBetween(curDate, start)<=0){ |
|
||||
return {remark:this.toFixed(this.getDaysBetween(start,curDate))+"天后开始",status:'primary'}; |
|
||||
}else if( this.getDaysBetween(curDate, start) > 0 && this.getDaysBetween(curDate, end) <= 0 ){ |
|
||||
return {remark: this.toFixed(this.getDaysBetween(end, curDate))+"天后结束",status:'primary'}; |
|
||||
}else if( this.getDaysBetween(curDate, end) > 0 ){ |
|
||||
return {remark:"逾期"+( this.toFixed(this.getDaysBetween(curDate, end)) )+"天",status:'danger'}; |
|
||||
} |
|
||||
}, |
|
||||
/** |
|
||||
* 计算两个日期之间的天数 |
|
||||
* @param dateString1 开始日期 yyyy-MM-dd |
|
||||
* @param dateString2 结束日期 yyyy-MM-dd |
|
||||
*/ |
|
||||
getDaysBetween(startDate,endDate){ |
|
||||
if (startDate==endDate){ |
|
||||
return 0; |
|
||||
} |
|
||||
var days=(startDate - endDate )/(1*24*60*60*1000); |
|
||||
return days; |
|
||||
}, |
|
||||
getSummariesForBatchEdit:function(params){ |
|
||||
const { columns, data } = params; |
|
||||
const sums = []; |
|
||||
sums[0]='' |
|
||||
sums[1]='总计'//名字 |
|
||||
sums[2]=''//进度 |
|
||||
sums[3]=''//开始结束时间 |
|
||||
sums[4]=''// 工期 工作量 成本金额 |
|
||||
|
|
||||
var workload=this.budgetData.budgetIuserWorkload+this.budgetData.budgetOuserWorkload |
|
||||
var cost=this.budgetData.budgetNouserAt+this.budgetData.budgetIuserAt+this.budgetData.budgetOuserAt |
|
||||
sums[4]='工作量:'+workload.toFixed(0)+'人时,预算金额:'+cost.toFixed(0)+'元,'+(cost/10000).toFixed(2)+'万元' |
|
||||
return sums; |
|
||||
}, |
|
||||
getSummariesForNoBatchEdit:function(params){ |
|
||||
const { columns, data } = params; |
|
||||
const sums = []; |
|
||||
sums[0]='' |
|
||||
sums[1]=''// |
|
||||
sums[2]='总计'//名字 |
|
||||
sums[3]=''//时间 |
|
||||
sums[4]=''//进度 |
|
||||
sums[5]=''//工作量 计划、实际 |
|
||||
sums[6]=''// 成本 计划、实际 |
|
||||
var budgetWorkload=this.budgetData.budgetIuserWorkload+this.budgetData.budgetOuserWorkload |
|
||||
|
|
||||
var actWorkload=this.budgetData.actWorkload |
|
||||
var budgetCost=this.budgetData.budgetNouserAt+this.budgetData.budgetIuserAt+this.budgetData.budgetOuserAt |
|
||||
var actCost=this.budgetData.actIuserAt+this.budgetData.actNouserAt+this.budgetData.actOuserAt |
|
||||
sums[5]='预算工作量:'+budgetWorkload+'人时,实际:'+actWorkload+'人时' |
|
||||
sums[6]='预算金额:'+budgetCost.toFixed(0)+'元,'+(budgetCost/10000).toFixed(2)+'万元,实际:'+actCost.toFixed(0)+'元,'+(actCost/10000).toFixed(2)+'万元' |
|
||||
|
|
||||
return sums; |
|
||||
}, |
|
||||
toFixed(floatValue,xsd){ |
|
||||
if(floatValue ==null || floatValue=='' || floatValue == undefined){ |
|
||||
return 0; |
|
||||
}else{ |
|
||||
if(xsd){ |
|
||||
if(typeof(floatValue)=='number'){ |
|
||||
return floatValue.toFixed(xsd) |
|
||||
}else{ |
|
||||
|
|
||||
return parseFloat(floatValue).toFixed(xsd); |
|
||||
} |
|
||||
}else{ |
|
||||
if(typeof(floatValue)=='number'){ |
|
||||
return floatValue.toFixed(0) |
|
||||
}else{ |
|
||||
|
|
||||
return parseFloat(floatValue).toFixed(0); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
showLog(row){ |
|
||||
this.editForm=row |
|
||||
this.xmRecordVisible=true |
|
||||
}, |
|
||||
// 判断前后两个数据是否存在同一回路里面 |
|
||||
// dict 为字典;sId拖拽到menuId; ePmeuId 是放置位置的祖先 menuId; |
|
||||
judgePmenuId(dict, sId, ePmeuId) { |
|
||||
if (sId === ePmeuId) { |
|
||||
return true; |
|
||||
} else if (dict[ePmeuId]) { |
|
||||
return this.judgePmenuId(dict, sId, dict[ePmeuId]); |
|
||||
} else { |
|
||||
return false; |
|
||||
} |
|
||||
}, |
|
||||
changePmenuId(sId, eId) { |
|
||||
let dict = {}; |
|
||||
this.xmPhases.forEach(d => { |
|
||||
dict[d.id] = d.parentPhaseId || ''; |
|
||||
}); |
|
||||
if (!dict[eId]) { |
|
||||
this.xmPhases.find(d => { |
|
||||
if (d.id === sId) { |
|
||||
d.parentPhaseId = eId; |
|
||||
console.log('更新关系1'); |
|
||||
this.fieldChange(d,'parentPhaseId',true); |
|
||||
} |
|
||||
}) |
|
||||
} else { |
|
||||
const isSynezesis = this.judgePmenuId(dict, sId, dict[eId]); |
|
||||
if (!isSynezesis) { |
|
||||
this.xmPhases.find(d => { |
|
||||
if (d.id === sId) { |
|
||||
d.parentPhaseId = eId; |
|
||||
console.log('更新关系2'); |
|
||||
this.fieldChange(d,'parentPhaseId',true); |
|
||||
} |
|
||||
}) |
|
||||
} else { |
|
||||
console.log('形成闭合回路--拖拽不更新'); |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
/**end 自定义函数请在上面加**/ |
|
||||
formateOption:function(itemCode,value){ |
|
||||
if(this.dicts[itemCode]){ |
|
||||
var dicts=this.dicts[itemCode].filter(i=>i.id==value); |
|
||||
if(dicts && dicts.length > 0){ |
|
||||
return dicts[0].name |
|
||||
}else{ |
|
||||
return value; |
|
||||
} |
|
||||
}else{ |
|
||||
return value |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
},//end methods |
|
||||
components: { |
|
||||
|
|
||||
//在下面添加其它组件 |
|
||||
}, |
|
||||
mounted() { |
|
||||
|
|
||||
this.$nextTick(() => { |
|
||||
|
|
||||
|
|
||||
this.tableHeight = util.calcTableMaxHeight(this.$refs.selectPhaseTable.$el); |
|
||||
if(this.selProject){ |
|
||||
this.getXmPhases(); |
|
||||
} |
|
||||
|
|
||||
initSimpleDicts('all',['xmPhaseStatus']).then(res=>{ |
|
||||
this.dicts=res.data.data; |
|
||||
}) |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
|
|
||||
.align-right{ |
|
||||
float: right; |
|
||||
} |
|
||||
</style> |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue