123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- <template>
- <div>
- <CollapseTransition>
- <div v-show="isShow">
- <div class="taskBox" v-if="projects.length>0">
- <div v-for="(item,index) in projects" :key="index" class="flex-box-ce isSimpleShow" @click.prevent.stop="openDetail2(item)">
- <div class="flex-1 clamp2" style="padding-right: 30px;">
- <i class="el-icon-s-finance" style="margin-right: 10px;"></i>
- <Tooltip :preHtml="item.name" class="hoverBlue"><span>{{item.name}}</span></Tooltip>
- </div>
- <template v-if="isParent">
- <div class="hover-border2"> <svg-icon icon-class="#icon-biaoqian_wode" class="svgIcon"></svg-icon><span>{{$getEmployeeMapItem(item.owner_id).name}}</span></div>
- <div class="hover-border2" style="margin: 0 30px;text-align: center;width: 52px;">
- <span>{{$moment(item.end_date).format('MM/DD')}}</span>
- </div>
- <div class="flex-box-ce" v-if="item.process">
- <el-progress :stroke-width="3" v-if="item.process>100" color="#2879ff" :show-text="false" :width="20" type="circle" :percentage="100"></el-progress>
- <el-progress :stroke-width="3" v-else :show-text="false" color="#2879ff" :width="20" type="circle" :percentage="Number(item.process)"></el-progress>
- <span style="padding-left: 5px;">{{item.process}}%</span>
- </div>
- <div v-if="item.can_edit" style="width: 20px;height: 20px;margin-left: 30px;cursor: pointer;" @click.prevent.stop="qxGl(item)">
- <Tooltip preHtml="取消关联"><i class="el-icon-link"></i></Tooltip>
- </div>
- <div v-else style="width: 20px;height: 20px;margin-left: 30px;"></div>
- </template>
- </div>
- </div>
- <div class="taskBox">
- <template v-if="parentList.length>0">
- <div v-for="(item,index) in parentList" :key="index">
- <div class="flex-box-ce isSimpleShow">
- <template v-if="isParent">
- <i class="caret" v-if="item.statistics.plan_total>0" :class="item.isShow? 'el-icon-caret-bottom':'el-icon-caret-right'" @click="showTask(item)"></i>
- </template>
- <template v-else>
- <i class="caret" v-if="item.child&&item.child.length>0" :class="item.isShow? 'el-icon-caret-bottom':'el-icon-caret-right'" @click="showTask(item)"></i>
- </template>
- <Tooltip :preHtml="item.stateInfo.name"><i :class="item.stateInfo.icon" style="margin-right: 10px;"></i></Tooltip>
- <!-- 可操作 -->
- <template v-if="isSimpleShow==1">
- <div class="flex-1 clamp2" style="padding-right: 30px;">
- <Tooltip :preHtml="item.name"><span class="hoverBlue" @click.prevent.stop="openDetail(item)">{{item.name}}</span></Tooltip>
- </div>
- <div class="hover-border" @click="openSelectTime(item,2)"> <svg-icon icon-class="#icon-biaoqian_wode" class="svgIcon"></svg-icon><span>{{item.userInfo.name}}</span></div>
- <div class="hover-border" style="margin: 0 30px;text-align: center;width: 52px;" @click="openSelectTime(item,1)">
- <span>{{$moment(item.end_date).format('MM/DD')}}</span>
- </div>
- <div class="flex-box-ce" v-if="item.process">
- <el-progress :stroke-width="3" v-if="item.process>100" :color="customColorMethod(item.level)" :show-text="false" :width="20" type="circle" :percentage="100"></el-progress>
- <el-progress :stroke-width="3" v-else :show-text="false" :color="customColorMethod(item.level)" :width="20" type="circle" :percentage="Number(item.process)"></el-progress>
- <span style="padding-left: 5px;">{{item.process}}%</span>
- </div>
- <template v-if="item.can_stop==1||item.can_cancel==1||item.can_finish==1||item.can_reset==1||isShowBinding">
- <el-dropdown @command="handleCommand($event,item)" trigger="click" class="hoverBlue">
- <i class="el-icon-more"></i>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item :command="1" v-if="item.can_stop==1">暂停任务</el-dropdown-item>
- <el-dropdown-item :command="2" v-if="item.can_cancel==1">取消任务</el-dropdown-item>
- <el-dropdown-item :command="3" v-if="item.can_finish==1">完成任务</el-dropdown-item>
- <el-dropdown-item :command="4" v-if="item.can_reset==1">重置任务</el-dropdown-item>
- <el-dropdown-item :command="5" v-if="isShowBinding&&item.can_edit_normal==1">取消关联</el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </template>
- <div v-else style="width: 20px;height: 20px;margin-left: 30px;"></div>
- </template>
- <!-- 不可操作 -->
- <template v-if="isSimpleShow==2">
- <div class="flex-1 clamp2" style="padding-right: 30px;">
- <Tooltip :preHtml="item.name"><span class="hoverBlue" @click.prevent.stop="openDetail(item)">{{item.name}}</span></Tooltip>
- </div>
- <div class="hover-border2"> <svg-icon icon-class="#icon-biaoqian_wode" class="svgIcon"></svg-icon><span>{{item.userInfo.name}}</span></div>
- <div class="hover-border2" style="margin: 0 30px;text-align: center;width: 52px;">
- <span>{{$moment(item.end_date).format('MM/DD')}}</span>
- </div>
- <div class="flex-box-ce" v-if="item.process">
- <el-progress :stroke-width="3" v-if="item.process>100" :color="customColorMethod(item.level)" :show-text="false" :width="20" type="circle" :percentage="100"></el-progress>
- <el-progress :stroke-width="3" v-else :show-text="false" :color="customColorMethod(item.level)" :width="20" type="circle" :percentage="Number(item.process)"></el-progress>
- <span style="padding-left: 5px;">{{item.process}}%</span>
- </div>
- <div style="width: 20px;height: 20px;margin-left: 30px;"></div>
- </template>
- <!-- 已结束 -->
- <template v-if="isSimpleShow==3">
- <div class="flex-1 clamp2 hoverBlue" @click.prevent.stop="openDetail(item)">
- <Tooltip :preHtml="item.name"><span>{{item.name}}</span></Tooltip>
- </div>
- <div class="hover-border2" v-if="item.composite_state==2||item.composite_state==3">
- <span v-if="item.day>0">剩余<span class="green">{{item.day}}</span>天</span>
- <span v-if="item.day<0">过期<span class="red">{{Math.abs(item.day)}}</span>天</span>
- </div>
- </template>
- </div>
- <template v-if="isParent">
- <TaskItem v-if="item.statistics.plan_total>0" :isShowBinding="false" :isShow="item.isShow" :isParent="isParent" :taskId="item.id" :isSimpleShow="isSimpleShow" @confirm="openDetail"></TaskItem>
- </template>
- <template v-else>
- <TaskItem v-if="item.child&&item.child.length>0" :isShowBinding="false" :isShow="item.isShow" :list="item.child" :isSimpleShow="isSimpleShow" @confirm="openDetail"></TaskItem>
- </template>
- </div>
- </template>
- <div v-else>
- <template v-if="isParent&&projects.length==0">
- <div class="zhu"></div>
- <div class="zhu"></div>
- </template>
- <template v-else>
- <div class="orange" v-if="projects.length==0&&parentList.length==0" style="margin-bottom: 8px;font-size: 13px;">用“项目/任务”推动目标达成,合理规划安排工作</div>
- </template>
- </div>
- </div>
- </div>
- </CollapseTransition>
- <TaskDetail v-if="isShowTaskDetail2" :visible.sync="isShowTaskDetail" :taskId="selectTaskItem.id" @confirm="closeDetail"></TaskDetail>
- <!-- 修改起止时间 -->
- <el-dialog title="修改起止时间" :visible.sync="isShowDqMyTarget" :append-to-body="true" width="600px">
- <div>
- <el-form ref="form" label-width="80px" class="form">
- <el-form-item label="起止时间">
- <el-date-picker :picker-options="instantPickerOptions" v-model="time"
- :clearable="false" type="datetimerange" range-separator="至" value-format="yyyy-MM-dd HH:mm:ss"
- start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['8:00:00', '18:00:00']"></el-date-picker>
- </el-form-item>
- </el-form>
- </div>
- <div class="flex-box-end" style="margin-top: 50px;">
- <el-button size="small" @click="isShowDqMyTarget = false">取 消</el-button>
- <el-button size="small" type="primary" @click="confirmTime">确 定</el-button>
- </div>
- </el-dialog>
- <!-- 选择负责人 -->
- <EmployeeSelector :is_filtration_creator="false" title="选择人员" :isChecKedAll="false" :isRequired="true" :multi="false" :selected="employee_selected" :visible.sync="show_employee_selector" @confirm="employee_confirm"/>
- </div>
- </template>
- <script>
- import Tooltip from '@/components/Tooltip'; //鼠标悬浮显示文字
- import TaskDetail from '@/okr/components/public/TaskDetail'; //任务详情
- import CollapseTransition from '@/okr/utils/collapse-transition';
- import {taskStatus} from '@/okr/utils/auth';
- import EmployeeSelector from '@/components/EmployeeSelector';
- import Progress from '@/okr/components/public/Progress'; //进度条
- import moment from 'moment' // 时间库
- export default {
- name:'TaskItem',
- components:{CollapseTransition,Tooltip,TaskDetail,EmployeeSelector,Progress},
- props:{
- isParent:{ //是否 一层层请求任务
- type: Boolean,
- default: false,
- },
- krId:{ //KrID
- type: Number,
- default: 0,
- },
- taskId:{ //任务ID
- type: Number,
- default: 0,
- },
- isShow:{
- type: Boolean,
- default: false,
- },
- isSimpleShow:{ // 1.任务里面的都可以点击操作 2.任务内容不可点击 3.只显示名称与时间
- type: Number,
- default: 1,
- },
- isShowBinding:{ //是否显示解绑
- type: Boolean,
- default: true,
- },
- list:{
- type:Array,
- default: function(){
- return []
- }
- },
- projectsList:{
- type:Array,
- default: function(){
- return []
- }
- },
- isShowChild:{ //项目的详情任务有用到
- type: Boolean,
- default: false,
- }
- },
- data() {
- return {
- userInfo: this.$userInfo(),
- parentList:[],
- time:[],
- selectTaskItem:{},
- isShowTaskDetail:false,
- isShowDqMyTarget:false,
- statusArr:taskStatus(),
- employee_selected: { dept: [], employee: [] },
- show_employee_selector: false,
- instantPickerOptions: {
- shortcuts: [
- {
- text: "今天",
- onClick(picker) {
- picker.$emit("pick", [`${moment().format('YYYY-MM-DD')} 08:00:00`,`${moment().format('YYYY-MM-DD')} 18:00:00`]);
- }
- },
- {
- text: "明天",
- onClick(picker) {
- picker.$emit("pick", [`${moment().add(1, "days").format('YYYY-MM-DD')} 08:00:00`,`${moment().add(1, "days").format('YYYY-MM-DD')} 18:00:00`]);
- }
- },
- {
- text: "本周",
- onClick(picker) {
- let start_date=moment().week(moment().week()).startOf('isoweek').format('YYYY-MM-DD 08:00:00')
- let end_date=moment().week(moment().week()).endOf('isoweek').format('YYYY-MM-DD 18:00:00')
- picker.$emit("pick", [start_date, end_date]);
- }
- },
- {
- text: "下周",
- onClick(picker) {
- let start_date=moment().week(moment().week() + 1).startOf('isoweek').format('YYYY-MM-DD 08:00:00')
- let end_date=moment().week(moment().week() + 1).endOf('isoweek').format('YYYY-MM-DD 18:00:00')
- picker.$emit("pick", [start_date, end_date]);
- }
- },
- {
- text: "本月",
- onClick(picker) {
- let start_date=moment().startOf('month').format('YYYY-MM-DD 08:00:00')
- let end_date=moment().endOf('month').format('YYYY-MM-DD 18:00:00')
- picker.$emit("pick", [start_date, end_date]);
- }
- },
- {
- text: "下个月",
- onClick(picker) {
- let start_date=moment().add(1, "month").startOf('month').format('YYYY-MM-DD 08:00:00')
- let end_date=moment().add(1, "month").endOf('month').format('YYYY-MM-DD 18:00:00')
- picker.$emit("pick", [start_date, end_date]);
- }
- }
- ]
- },
- isShowTaskDetail2:false,
- projects:[],
- };
- },
- watch: {
- isShow(val){
- if(val){
- this.parentList=[];
- if(this.isParent){ //KR进来
- if(!this.isShowChild){
- this.getTask();
- }else{
- let list=this.list;
- list.forEach(item=>{
- item.stateInfo=taskStatus(item.composite_state);
- item.userInfo=this.$getEmployeeMapItem(item.owner_id);
- item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day');
- item.isShow=false;
- })
- // console.log("渲染了",list,this.isParent,this.isShowChild)
- this.parentList=list;
- }
- }else{
- let list=this.list;
- list.forEach(item=>{
- item.stateInfo=taskStatus(item.composite_state);
- item.userInfo=this.$getEmployeeMapItem(item.owner_id);
- item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day');
- item.isShow=false;
- })
- this.parentList=list;
- this.projects=this.projectsList
- }
- }
- },
- isShowTaskDetail(val){
- if(!val){
- this.isShowTaskDetail2=false;
- }
- }
- },
- methods: {
- customColorMethod(index) {
- // if (index ==1) {
- return '#2879ff';
- // } else if (index ==2) {
- // return '#FF9600';
- // } else {
- // return '#F16060';
- // }
- },
- closeDetail(){
- this.$emit('confirm',{});
- },
- //取消关联
- deleteFeedback(item){
- let params={plan_id:item.id,type:2,target_type:2,target_id:item.kr_id};
- if(item.others.length>0&&this.krId!=item.kr_id){
- params.type=3;
- params.target_id=this.krId;
- }
- this.$axiosUser('POST', 'api/pro/okr/plan/relate/delete', params).then(res => {
- this.closeDetail();
- })
- },
- qxGl(item){
- this.$confirm('确定取消关联吗?','提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- this.$axiosUser('POST', 'api/pro/okr/project/unbind', {project_id:item.id,kr_id:this.krId}).then(res => {
- this.closeDetail();
- })
- }).catch(() => {});
- },
- handleCommand(e,item){
- let url="";
- if(e==1){//暂停任务
- url="api/pro/okr/plan/state/stop";
- }else if(e==2){//取消任务
- url="api/pro/okr/plan/state/cancel";
- }else if(e==3){//完成任务
- url="api/pro/okr/plan/state/finish";
- }else if(e==4){//重置任务
- url="api/pro/okr/plan/state/reset";
- }else if(e==5){//取消关联
- this.$confirm('确定取消关联吗?','提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- this.deleteFeedback(item);
- }).catch(() => {});
- return false
- }
- this.$axiosUser('post', url, {plan_id:item.id}).then(res => {
- this.closeDetail();
- })
- },
- employee_confirm(val){
- let user=val.employee[0]
- let params={plan_id:this.selectTaskItem.id,owner_id:user.id};
- this.$axiosUser('POST', 'api/pro/okr/plan/owner', params).then(res => {
- this.selectTaskItem.userInfo=user
- this.$forceUpdate();
- })
- },
- confirmTime(){
- if(!this.time||this.time.length==0){
- this.$message.error("请选择时间");
- return false
- }
- let params={
- plan_id:this.selectTaskItem.id,
- start_date:this.time[0],
- end_date:this.time[1],
- }
- this.$axiosUser('post', 'api/pro/okr/plan/time', params).then(res => {
- this.selectTaskItem.start_date=params.start_date
- this.selectTaskItem.end_date=params.end_date
- }).finally(()=>{
- this.isShowDqMyTarget=false;
- })
- },
- openSelectTime(item,index){
- this.selectTaskItem=item;
- if(index==1){
- this.time=[item.start_date,item.end_date]
- this.isShowDqMyTarget=true;
- }else if(index==2){
- this.employee_selected.employee=[item.userInfo];
- this.show_employee_selector=true;
- }
- },
- getTask(){
- let data={};
- let url={};
- if(this.krId){
- data.kr_id=this.krId
- url="api/pro/okr/kr/sub/list"
- }else{
- data.plan_id=this.taskId
- url="api/pro/okr/plan/list/sub"
- }
- this.$axiosUser('get',url,data).then(res => {
- let list=this.krId? res.data.data.plans:res.data.data.list;
- list.forEach(item=>{
- item.isShow=false;
- item.stateInfo=taskStatus(item.composite_state);
- item.userInfo=this.$getEmployeeMapItem(item.owner_id)
- })
- this.parentList=list;
- if(this.krId){
- this.projects=res.data.data.projects;
- }
- })
- },
- openDetail2(item){
- this.$router.push({path:'/projectDetail',query:{id:item.id}})
- },
- openDetail(item){
- if(!item.id){
- return false
- }
- this.selectTaskItem=item;
- this.isShowTaskDetail2=true;
- this.$nextTick(()=>{
- this.isShowTaskDetail=true;
- })
- },
- showTask(item){
- item.isShow=!item.isShow;
- },
- inputBlur(){
- this.is=!this.is
- }
- }
- };
- </script>
- <style scoped="scoped" lang="scss">
- .hover-border2{
- padding: 3px;
- border-radius: 5px;
- // cursor: pointer;
- }
- .isSimpleShow{
- padding: 4px 0;
- position: relative;
- margin-bottom: 8px;
- border-radius: 5px;
- }
- .isSimpleShow:hover {
- background-color: #f4f6f9;
- }
- .zhu{
- height: 14px;
- width: 160px;
- background-color: #F0F4FA;
- margin-bottom: 10px;
- border-radius: 5px;
- }
- .taskBox{
- padding-left: 24px;
- }
- .caret{
- position: absolute;
- width: 30px;
- height: 30px;
- text-align: center;
- line-height: 30px;
- left: -30px;
- top: 50%;
- margin-top: -15px;
- box-sizing: border-box;
- cursor: pointer;
- }
- .el-icon-more{
- width: 20px;
- height: 20px;
- box-sizing: border-box;
- text-align: center;
- line-height: 20px;
- margin-left: 30px;
- cursor: pointer;
- }
- .el-icon-more:hover{
- background-color: #606266;
- border-radius: 25px;
- color: #fff;
- }
- .dialog-task-detail ::v-deep .el-dialog__header,.dialog-task-detail ::v-deep .el-dialog__body {
- padding: 0px;
- border: none;
- }
- </style>
|