3 changed files with 339 additions and 6 deletions
-
2package.json
-
324src/views/xm/core/xmTask/XmTaskAgileKanban.vue
-
19src/views/xm/core/xmTask/XmTaskMng.vue
@ -0,0 +1,324 @@ |
|||||
|
<template> |
||||
|
<section class="menu-box"> |
||||
|
<!-- <div class="itxst"> |
||||
|
<div class="col"> |
||||
|
<div class="title">A列</div> |
||||
|
<draggable v-model="arr1" group="site" animation="300" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd"> |
||||
|
<transition-group> |
||||
|
<div class="item" v-for="item in arr1" :key="item.id">{{item.name}}</div> |
||||
|
</transition-group> |
||||
|
</draggable> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="title">B列</div> |
||||
|
<draggable v-model="arr2" group="site" animation="100" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd"> |
||||
|
<transition-group> |
||||
|
<div class="item" v-for="item in arr2" :key="item.id">{{item.name}}</div> |
||||
|
</transition-group> |
||||
|
</draggable> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="title">C列</div> |
||||
|
<draggable v-model="arr3" group="c" animation="100" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd"> |
||||
|
<transition-group> |
||||
|
<div class="item" v-for="item in arr3" :key="item.id">{{item.name}}</div> |
||||
|
</transition-group> |
||||
|
</draggable> |
||||
|
</div> |
||||
|
</div> --> |
||||
|
<div class="row head-row"> |
||||
|
<div class="item">故事({{ menus.length }})</div> |
||||
|
<template v-for="(type, tt) in taskType"> |
||||
|
<div class="item status" :key="tt">{{type.label}} ({{ type.number }})</div> |
||||
|
</template> |
||||
|
</div> |
||||
|
<div class="menu-body"> |
||||
|
<div class="row menu—row" v-for="(menu, index) in menus" :key="index"> |
||||
|
<div class="item item-menu"> |
||||
|
<span> |
||||
|
{{menu.sortLevel}} |
||||
|
<!-- <el-dropdown @command="handleCommand" v-if=" isTaskCenter!='1' && isMy!='1'"> |
||||
|
<span class="el-dropdown-link"> |
||||
|
<el-button size="mini" circle><i class="el-icon-plus"></i></el-button> |
||||
|
</span> |
||||
|
<el-dropdown-menu slot="dropdown"> |
||||
|
<el-dropdown-item :command="{type:'showMenu',data:menu}">+由故事创建子任务(推荐)</el-dropdown-item> |
||||
|
<el-dropdown-item :command="{type:'showSubAdd',data:menu}">+子任务</el-dropdown-item> |
||||
|
<el-dropdown-item :command="{type:'showTaskTemplate',data:menu}">+从模板批量导入子任务</el-dropdown-item> |
||||
|
<el-dropdown-item :command="{type:'handleDel',data:menu}" icon="el-icon-delete">删除</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</el-dropdown> --> |
||||
|
<el-tag v-if="menu.level<='2'" type="info">轻微</el-tag> |
||||
|
<el-tag v-else-if="menu.level=='3'" type="warning">一般</el-tag> |
||||
|
<el-tag v-else-if="menu.level=='4'" type="danger">紧急</el-tag> |
||||
|
<el-tag v-else type="danger">特急</el-tag> |
||||
|
<span v-for="(item ,index) in [formatExeUsernames(menu)]" :key="index"> |
||||
|
|
||||
|
<el-tooltip :content="item.exeUsernames" ><el-link :type="item.type" @click.stop="showExecusers(menu)">{{item.showMsg}}</el-link></el-tooltip> |
||||
|
|
||||
|
</span> |
||||
|
<el-tooltip content="进度"><el-link style="border-radius:30px;" :type="menu.rate>=100?'success':'warning'" @click="drawerVisible=true"> {{ (menu.rate!=null?menu.rate:0)+'%'}} </el-link></el-tooltip> |
||||
|
<el-tooltip content="预算金额、工时"><el-tag type="info">{{parseFloat(menu.budgetCost/10000).toFixed(2)}}万,{{menu.budgetWorkload}}人时</el-tag></el-tooltip> |
||||
|
<el-link type="primary" @click.stop="showDrawer(menu)">{{menu.name}}</el-link> |
||||
|
</span> |
||||
|
</div> |
||||
|
<div class="item status" v-for="(type, tt) in taskType" :key="tt"> |
||||
|
<draggable |
||||
|
v-model="tasks[menu.menuId][tt]" |
||||
|
:name="menu.menuId" |
||||
|
@start="onStart" @end="onEnd" :move="onMove" |
||||
|
:options="{group: menu.menuId}" |
||||
|
class="draggable" |
||||
|
animation="300" |
||||
|
scroll |
||||
|
> |
||||
|
<transition-group class="transition-group" :data-menu-id="menu.menuId" :data-task-state="type.status"> |
||||
|
<template |
||||
|
v-if="tasks && tasks[menu.menuId][tt].length" |
||||
|
> |
||||
|
<div |
||||
|
:data-menu-id="menu.menuId" |
||||
|
:data-task-id="task.id" |
||||
|
:data-task-state="task.taskState" |
||||
|
class="task" |
||||
|
v-for="(task, t) in tasks[menu.menuId][tt]" |
||||
|
:key="t" |
||||
|
> |
||||
|
<span> |
||||
|
{{task.sortLevel}} |
||||
|
<!-- <el-dropdown @command="handleCommand" v-if=" isTaskCenter!='1' && isMy!='1'"> |
||||
|
<span class="el-dropdown-link"> |
||||
|
<el-button size="mini" circle><i class="el-icon-plus"></i></el-button> |
||||
|
</span> |
||||
|
<el-dropdown-menu slot="dropdown"> |
||||
|
<el-dropdown-item :command="{type:'showMenu',data:task}">+由故事创建子任务(推荐)</el-dropdown-item> |
||||
|
<el-dropdown-item :command="{type:'showSubAdd',data:task}">+子任务</el-dropdown-item> |
||||
|
<el-dropdown-item :command="{type:'showTaskTemplate',data:task}">+从模板批量导入子任务</el-dropdown-item> |
||||
|
<el-dropdown-item :command="{type:'handleDel',data:task}" icon="el-icon-delete">删除</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</el-dropdown> --> |
||||
|
<el-tag v-if="task.level<='2'" type="info">轻微</el-tag> |
||||
|
<el-tag v-else-if="task.level=='3'" type="warning">一般</el-tag> |
||||
|
<el-tag v-else-if="task.level=='4'" type="danger">紧急</el-tag> |
||||
|
<el-tag v-else type="danger">特急</el-tag> |
||||
|
<span v-for="(item ,index) in [formatExeUsernames(task)]" :key="index"> |
||||
|
|
||||
|
<el-tooltip :content="item.exeUsernames" ><el-link :type="item.type" @click.stop="showExecusers(task)">{{item.showMsg}}</el-link></el-tooltip> |
||||
|
|
||||
|
</span> |
||||
|
<el-tooltip content="进度"><el-link style="border-radius:30px;" :type="task.rate>=100?'success':'warning'" @click="drawerVisible=true"> {{ (task.rate!=null?task.rate:0)+'%'}} </el-link></el-tooltip> |
||||
|
<el-tooltip content="预算金额、工时"><el-tag type="info">{{parseFloat(task.budgetCost/10000).toFixed(2)}}万,{{task.budgetWorkload}}人时</el-tag></el-tooltip> |
||||
|
<el-link type="primary" @click.stop="showDrawer(task)">{{task.name}}</el-link> |
||||
|
</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</transition-group> |
||||
|
</draggable> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import draggable from "vuedraggable"; |
||||
|
import { editXmTask } from '@/api/xm/core/xmTask'; |
||||
|
|
||||
|
export default { |
||||
|
name: "XmTaskAgileKanban", |
||||
|
props: ["xmTasks"], |
||||
|
data() { |
||||
|
return { |
||||
|
taskType: [ |
||||
|
{ label: "待领取", status: 0, number: 0 }, |
||||
|
{ label: "已领取执行中", status: 1, number: 0 }, |
||||
|
{ label: "已完工", status: 2, number: 0 }, |
||||
|
{ label: "已结算", status: 3, number: 0 }, |
||||
|
], |
||||
|
tasks: {}, |
||||
|
drag: false, |
||||
|
arr1: [ |
||||
|
{ id: 1, name: 'www.itxst.com' }, |
||||
|
{ id: 2, name: 'www.jd.com' }, |
||||
|
{ id: 3, name: 'www.baidu.com' }, |
||||
|
{ id: 4, name: 'www.taobao.com' } |
||||
|
], |
||||
|
arr2: [ |
||||
|
{ id: 1, name: 'www.google.com' }, |
||||
|
{ id: 2, name: 'www.msn.com' }, |
||||
|
{ id: 3, name: 'www.ebay.com' }, |
||||
|
{ id: 4, name: 'www.yahoo.com' } |
||||
|
], |
||||
|
arr3: [ |
||||
|
{ id: 1, name: 'item 1' }, |
||||
|
{ id: 2, name: 'item 2' }, |
||||
|
{ id: 3, name: 'item 3' }, |
||||
|
{ id: 4, name: 'item 4' } |
||||
|
] |
||||
|
}; |
||||
|
}, |
||||
|
components: { draggable }, |
||||
|
watch: { |
||||
|
tasks: { |
||||
|
handler(val, oldVal) { |
||||
|
console.log('tasks--val==', val); |
||||
|
console.log('tasks--oldVal==', oldVal); |
||||
|
}, |
||||
|
deep: true, |
||||
|
immediate: true |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
menus() { |
||||
|
let xmTasks = JSON.parse(JSON.stringify(this.xmTasks || [])); |
||||
|
console.log('--xmTasks==', xmTasks); |
||||
|
|
||||
|
let menus = [], menuIds = {}, tasks = {}; |
||||
|
this.taskType.map(d => { |
||||
|
d.number = 0; |
||||
|
return d; |
||||
|
}) |
||||
|
xmTasks.forEach((d, i) => { |
||||
|
if (!menus.length || !menuIds[d.menuId]) { |
||||
|
menus.push(d); |
||||
|
menuIds[d.menuId] = true; |
||||
|
} else { |
||||
|
console.log('i==', i); |
||||
|
} |
||||
|
if (!tasks[d.menuId]) { |
||||
|
tasks[d.menuId] = [[], [], [], []]; |
||||
|
} |
||||
|
tasks[d.menuId][parseInt(d.taskState)].push(d); |
||||
|
this.taskType[parseInt(d.taskState)].number += 1; |
||||
|
}); |
||||
|
this.tasks = tasks; |
||||
|
console.log('this.tasks==', this.tasks); |
||||
|
return menus; |
||||
|
}, |
||||
|
}, |
||||
|
methods: { |
||||
|
onStart(e) { |
||||
|
console.log('onStart--e==', e); |
||||
|
this.drag = true; |
||||
|
}, |
||||
|
onEnd(e) { |
||||
|
console.log('onEnd--e==', e); |
||||
|
this.drag = false; |
||||
|
// targetEl:拖拽的任务数据; toEl拖拽后的位置. |
||||
|
let targetEl = { ...e.item.dataset }; |
||||
|
let toEl = { ...e.to.dataset }; |
||||
|
console.log('onEnd--targetEl==', targetEl, toEl); |
||||
|
if (targetEl.menuId === toEl.menuId && targetEl.taskState !== toEl.taskState) { |
||||
|
let task = this.xmTasks.find(d => d.id === targetEl.taskId); |
||||
|
console.log('onEnd--task==', task); |
||||
|
const params = { ...task, taskState: toEl.taskState }; |
||||
|
editXmTask(params).then(res => { |
||||
|
console.log('onEnd--editXmTask--res==', res); |
||||
|
this.$emit('submit'); |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
formatExeUsernames(row){ |
||||
|
var exeUsernames=row.exeUsernames; |
||||
|
var respons={ |
||||
|
type:'info', |
||||
|
executorUsername:row.executorUsername, |
||||
|
showMsg:'', |
||||
|
exeUsernames:exeUsernames, |
||||
|
executorUserid:row.executorUserid, |
||||
|
} |
||||
|
if(!row.executorUserid && exeUsernames){ |
||||
|
var exeStatuss=exeUsernames.split(",") |
||||
|
respons.showMsg=exeStatuss.length+"人候选中" |
||||
|
return respons; |
||||
|
}else if(!row.executorUserid && !exeUsernames){ |
||||
|
respons.showMsg="候选中" |
||||
|
return respons; |
||||
|
} |
||||
|
if(row.executorUserid && exeUsernames && exeUsernames.length>0){ |
||||
|
var exeStatuss=exeUsernames.split(",").filter(i=>{ |
||||
|
return i.indexOf(row.executorUsername)>=0 |
||||
|
}) |
||||
|
if(exeStatuss.length<=0){ |
||||
|
respons.showMsg="去设置" |
||||
|
return respons; |
||||
|
} |
||||
|
respons.showMsg=exeStatuss.join(",") |
||||
|
if(respons.showMsg.indexOf('验收不过')>=0){ |
||||
|
respons.type="danger" |
||||
|
}else if(respons.showMsg.indexOf('已验收')>=0){ |
||||
|
respons.type="success" |
||||
|
} |
||||
|
}else{ |
||||
|
respons.showMsg="去设置" |
||||
|
} |
||||
|
return respons |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang='scss' scoped> |
||||
|
.menu-box { |
||||
|
width: 100%; |
||||
|
overflow: scroll; |
||||
|
} |
||||
|
.row { |
||||
|
width: 2000px; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
overflow: scroll !important; |
||||
|
border-top: 1px solid #ccc; |
||||
|
.item { |
||||
|
width: 200px; |
||||
|
padding: 10px; |
||||
|
border-left: 1px solid #ccc; |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
&.status { |
||||
|
width: 450px; |
||||
|
} |
||||
|
&:last-child { |
||||
|
border-right: 1px solid #ccc; |
||||
|
} |
||||
|
} |
||||
|
&:last-child { |
||||
|
border-bottom: 1px solid #ccc; |
||||
|
} |
||||
|
&.head-row { |
||||
|
font-size: 14px; |
||||
|
font-weight: 500; |
||||
|
background: #efefef; |
||||
|
color: #303030; |
||||
|
} |
||||
|
&.menu—row { |
||||
|
background: #f6f6f6; |
||||
|
.item-menu { |
||||
|
background: #ffffff; |
||||
|
} |
||||
|
.task { |
||||
|
width: 200px; |
||||
|
height: 100px; |
||||
|
margin: 10px 0 0 10px; |
||||
|
// padding: 10px; |
||||
|
cursor: pointer; |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
border-radius: 3px; |
||||
|
// box-shadow: 0 2px 12px 0 rgb(48 48 48 / 5%), 0 2px 4px 0 rgb(48 48 48 / 10%); |
||||
|
|
||||
|
background-color: #fff; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.draggable { |
||||
|
min-height: 100px; |
||||
|
width: 100%; |
||||
|
} |
||||
|
.transition-group { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
min-height: 100px; |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue