123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 |
- <template>
- <div style="height: 100%;">
- <van-nav-bar title="目标管理" left-text="返回" @click-left="$route_back" left-arrow>
- <div slot="right" @click="isShowPopup = true" style="color: #fff;">筛选<van-icon name="list-switch" /></div>
- </van-nav-bar>
- <div class="all">
- <div style="background-color: #fff;">
- <div style="padding: 0.24rem;border-bottom: 1px solid #f1f1f1;" class="flex-box-ce flex-center-center" @click="openPanel()">
- <icon name="YMPicker_item_icon" style="margin-right: 6px;width: 0.3rem;height: 0.3rem;" class="fontColorC"></icon>
- <div>{{ dateParameter.year }}年</div>
- <div style="margin: 0 6px;">{{ dateParameter.name }}</div>
- <van-icon name="arrow-down" />
- </div>
- <!-- <van-tabs v-model="activeName">
- <van-tab v-for="(item,index) in tabs" :title="item.title" :name="item.name" :key="index" v-if="item.isShow"></van-tab>
- </van-tabs> -->
- </div>
- <template v-if="activeName=='a'">
- <!-- <div class="flex-box-ce flex-d-wrap" style="padding: 0 0.2rem;margin-top: 0.24rem;">
- <div class="search-item" style="border-radius: 25px;font-size: 0.28rem;" @click="targetType=item.id" v-for="(item, index) in targetTypeArr" :key="index" :class="item.id==targetType? 'searchActive':''">{{ item.name }}</div>
- </div> -->
- </template>
- <template v-if="activeName=='b'">
- <div class="selector" @click="isShowDept=true">
- <span>{{ deptInfo.dept_name }}</span>
- <van-icon name="arrow-down" />
- </div>
- <div style="overflow-x: scroll;margin: 0.2rem;">
- <div class="flex-box-ce">
- <div
- :class="{userActive:ownerUserInfo.id==item.id}"
- @click="ownerUserInfo = item"
- style="padding:0.14rem;border-radius: 5px;"
- class="flex-box-v flex-center-center"
- v-for="(item,index) in userList" :key="index">
- <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
- <div class="clamp userName">{{item.name}}</div>
- </div>
- </div>
- </div>
- </template>
- <template v-if="activeName=='c'">
- <div style="overflow-x: scroll;margin: 0.2rem;">
- <div class="flex-box-ce">
- <div class="flex-box-v flex-center-center" style="padding: 0.14rem;" @click="openGz">
- <div class="addUser" style="">+</div>
- <div class="clamp userName">设置</div>
- </div>
- <div
- :class="{userActive:follUserInfo.id==item.id}"
- @click="follUserInfo=item"
- style="padding:0.14rem;border-radius: 5px;"
- class="flex-box-v flex-center-center"
- v-for="(item,index) in followList" :key="index">
- <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
- <div class="clamp userName">{{item.name}}</div>
- </div>
- </div>
- </div>
- </template>
- <template v-if="activeName=='d'">
- <div class="selector" @click="isShowSelectUser=true">
- <span v-if="selectDataBox.name">{{ selectDataBox.name }}</span>
- <span v-else class="fontColorC">选择人员或部门</span>
- <van-icon name="arrow-down" />
- </div>
- <div style="height: 0.2rem;"></div>
- </template>
- <div class="scroller" :class="{scroller2:activeName=='b',scroller3:activeName=='c',scroller4:activeName=='d'}">
- <scroller ref="scroller" :isInitRefresh="false" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢" :list="targetList">
- <div class="list-box" v-for="(item,index) in targetList" :key="index" >
- <div class="flex-box" @click="openDetail(item,1)">
- <div class="huan"><span></span></div>
- <div class="flex-1">
- <div class="clamp2" style="margin-bottom: 5px;">{{item.name}}</div>
- <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
- <van-icon name="contact" v-show="item.belong_type==4"/>
- <van-icon name="cluster-o" v-show="item.belong_type==2"/>
- <van-icon name="hotel-o" v-show="item.belong_type==1"/>
- <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;">{{$getEmployeeMapItem(item.owner_id).name}}</span>
- <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.composite_state==6">已结束</span>
- <template v-else>
- <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.process_ut">{{item.process_ut}} 更新</span>
- </template>
- <span class="flex-1"></span>
- <div class="progress"><div class="progress-inner" :class="{bjYellow:item.risk_level==2,bjRed:item.risk_level==3}" :style="{width:item.process>100? '100%':item.process+'%'}"></div></div>
- <span style="padding-left: 0.1rem;font-size: 0.24rem;" class="blue" :class="{orange:item.risk_level==2,red:item.risk_level==3}">{{ item.process }}%</span>
- </div>
- </div>
- </div>
- <div class="flex-box-ce" style="margin-top: 0.2rem;" @click="openDetail(krItem,2)" v-for="(krItem,index2) in item.krs" :key="index2" >
- <div class="blue" style="font-size: 0.26rem;margin-right: 0.13rem;">KR{{index2+1}}</div>
- <div class="flex-1 font-flex-word" style="padding-right: 0.2rem;font-size: 0.28rem;">{{krItem.name}}</div>
- <van-circle layer-color="#E5E9F2" v-model="krItem.currentRate" :color="krItem.risk_level==2? '#FF9600':krItem.risk_level==3? '#f56c6c':' #2879ff'" :rate="krItem.process" :key="index2" :stroke-width="120" size="20px"/>
- <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:krItem.risk_level==2,red:krItem.risk_level==3}">{{ krItem.process }}%</span>
- </div>
- </div>
- <div v-if="targetList.length == 0" style="text-align: center;margin-top: 2rem;" class="fontColorC">
- <span>未找到相关的目标</span>
- </div>
- </scroller>
- </div>
- </div>
- <!-- 选择部门 -->
- <van-dialog v-model="isShowDept" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
- <van-radio-group v-model="deptInfo.dept_id">
- <div v-for="(item, index) in dept_list" :key="index">
- <van-radio :name="item.dept_id" @click="confirmDept2(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
- <span style="margin-left:.3rem">{{ item.dept_name }}</span>
- </van-radio>
- </div>
- </van-radio-group>
- </van-dialog>
- <!-- 周期选择 -->
- <van-action-sheet v-model="pullonThePanel" :closeable="false">
- <div class="content">
- <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel=false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
- </div>
- </van-action-sheet>
- <!-- 人员选择 -->
- <EmployeeDeptSelector
- title="选择人员"
- :visible.sync="isShowSelectUser"
- @confirm="confirmUser"
- :selectDataBox.sync="selectDataBox">
- </EmployeeDeptSelector>
- <!-- 筛选 -->
- <van-popup v-model="isShowPopup" position="right" style="height: 100%;left: 20%;">
- <div style="position: relative;height: 100%;">
- <div style="border-bottom: 1px solid #f1f1f1;font-size: 16px;font-weight: 700;height: 0.92rem;line-height: 0.92rem;padding: 0 0.2rem;">高级筛选</div>
- <div style="padding: 10px;">
- <div style="margin-bottom: 15px;font-size: 0.32rem;">类型</div>
- <div class="flex-box-ce flex-d-wrap">
- <div class="search-item" @click="belong_type=item.id" v-for="(item, index) in targetArr" :key="index" :class="item.id==belong_type? 'searchActive':''">{{ item.name }}</div>
- </div>
- </div>
- <!-- <div style="padding: 10px;">
- <div style="margin-bottom: 15px;font-size: 0.32rem;">状态</div>
- <div class="flex-box-ce flex-d-wrap">
- <div class="search-item" @click="sortId=item.id" v-for="(item, index) in sortArr" :key="index" :class="item.id==sortId? 'searchActive':''">{{ item.name }}</div>
- </div>
- </div> -->
- <div style="position: fixed;bottom: 0.2rem;left: 0.2rem;right: 0.2rem;">
- <div class="btn" @click="isShowPopup=false">确认</div>
- </div>
- </div>
- </van-popup>
- </div>
- </template>
- <script>
- import Vue from 'vue';
- import {Picker,Popup,Circle,Icon,Tab, Tabs,} from 'vant';
- import { _debounce, _throttle } from '@/utils/auth';
- import { getBelongType,getColumns,cycleTypeArr} from '@/okr/utils/auth';
- import EmployeeSelector from '@/components/EmployeeSelector';
- import EmployeeDeptSelector from '@/components/EmployeeDeptSelector';
- Vue.use(Picker).use(Popup).use(Circle).use(Icon).use(Tabs).use(Tab)
- export default {
- components:{EmployeeSelector,EmployeeDeptSelector},
- name: 'Target',
- props: {
- skeLoad: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- page:1,
- page_size:10,
- cycleTypeArr:cycleTypeArr(true),
- value:5,
- userId:this.$userInfo().id,
- userInfo: this.$userInfo(),
- dept_list:this.$userInfo().employee_detail.dept_list,
- deptInfo:this.$userInfo().employee_detail.dept_list[0]? this.$userInfo().employee_detail.dept_list[0]:{},
- isShowDept:false,
- targetTypeArr: [{ name: '我负责的', id: 1 }, { name: '我参与的', id: 2 }, { name: '我关注的', id: 3 }],
- targetType:1,
- dateParameter: {
- year: '',
- cycle_type: 0,
- dateId: 1,
- name: '全部周期'
- },
- selectPftiTheEcho: [0, 0], // 选项回显
- pullonThePanel:false,
- columns: getColumns(),
- isShowPopup:false,
- targetArr: [{ name: '全部类型', id: 0 }, { name: '公司', id: 1 }, { name: '部门', id: 2 },{ name: '个人', id: 4 }],
- belong_type: 0,
- sortArr: [
- { name: '全部状态', id: 0,value:'0' },
- { name: '进行中', id: 1,value:'1,2,3,4,5,7,8,9' },
- { name: '已结束', id: 2,value:'6' },
- ],
- sortId: 0,
- targetList:[],
- isShowSelectUser:false,
- selected_user: { dept: [], employee: [] } ,//传入已选部门
- selectDataBox:{},
- tabs:[{title:'我的目标',name:'a',isShow:true},{title:'我的部门',name:'b',isShow:true},{title:'关注的人',name:'c',isShow:true},{title:'全公司',name:'d',isShow:true}],
- activeName: 'd',
- userList:[],
- ownerUserInfo:{},
- followList:[],
- follUserInfo:{},
- };
- },
- watch:{
- isShowSelectUser(val){
- if(val){
- this.selected_user.employee=[this.userInfo];
- }
- },
- isShowPopup(val){
- if(!val){
- this.pullDown();
- }
- },
- targetType(){
- this.pullDown();
- },
- ownerUserInfo(){
- this.pullDown();
- },
- follUserInfo(){
- this.pullDown();
- },
- activeName(val){
- if(this.activeName=='a'){
- this.pullDown();
- }
- if(this.activeName=='d'){
- this.pullDown();
- }
- if(this.activeName=='b'){
- this.get_employee_list();
- }
- if(this.activeName=='c'){
- this.getGzUserList();
- }
- },
- },
- methods: {
- openGz(){
- this.$router.push({name: 'attentionList',query:{index:1}})
- },
- getGzUserList(){
- this.$axiosUser('get', '/api/pro/okr/follow', { type:1 }).then(res=>{
- this.followList = res.data.data.list;
- if(this.followList.length>0){
- this.follUserInfo=this.followList[0];
- }else{
- this.follUserInfo={};
- this.pullDown();
- }
- })
- },
- confirmDept2(data){
- this.deptInfo=JSON.parse(JSON.stringify(data));
- this.get_employee_list();
- this.isShowDept=false;
- },
- get_employee_list() {
- this.$axiosUser('get', '/api/pro/employee/list', { dept_id:this.deptInfo.dept_id }, 'v2').then(res => {
- let list=res.data.data.list;
- list.unshift({name:'全部',id:0})
- this.userList=list;
- if(this.userList.length>0){
- this.ownerUserInfo=this.userList[0];
- }
- });
- },
- openPanel(){
- this.pullonThePanel=true;
- this.$nextTick(() => {
- this.theEchoVanPicker()
- })
- },
- confirmUser(item){
- this.selectDataBox = item;
- this.pullDown();
- },
- openDetail(item,type){
- if(type==1){
- this.$router.push({name: 'myTargetDetail', query: {id: item.id}})
- }else {
- this.$router.push({name: 'myKrDetail', query: {id: item.id}})
- }
- },
- // 考核包搜索
- onConfirm (data, list) { // 确认
- let columns=this.columns[list[0]];
- let options=this.cycleTypeArr[list[1]]
- this.selectPftiTheEcho=list
- this.dateParameter={
- year: columns.value,
- cycle_type: options.cycle_type,
- dateId: options.id,
- name: options.name
- };
- this.pullDown();
- this.pullonThePanel = false
- },
- pullDown(){
- setTimeout(() => {
- this.$refs.scroller.triggerPullToRefresh();
- }, 50);
- },
- theEchoVanPicker() { // 回显
- this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
- },
- getList(is,callback){
- let hasMore = false
- is? '':this.page=1;
- let params = {
- page:is? this.page:1,
- page_size: this.page_size,
- cycle_type:this.dateParameter.cycle_type,
- year:this.dateParameter.year,
- belong_type:this.belong_type,
- quarter:0,
- half_year:0,
- month:0,
- sort_ct:2,
- ids: []
- };
- if(!params.year) delete params.year
- if(!params.quarter) delete params.quarter
- if(!params.half_year) delete params.half_year
- if(!params.month) delete params.month
- params.ids = this.$route.query.ids || "[]";
- if(this.activeName=='a'){ //我的目标
- this.targetType==1? params.owner_id=this.userId:this.targetType==2? params.joiner_id=this.userId:params.follower_id=this.userId;
- }else if(this.activeName=='b'){//我的部门
- params.dept=this.deptInfo.dept_id;
- params.owner_id=this.ownerUserInfo.id;
- }else if(this.activeName=='c'){//我关注的
- if(this.follUserInfo.id){
- params.owner_id=this.follUserInfo.id;
- }else{
- this.targetList=[];
- callback && callback(hasMore)
- return false
- }
- }else if(this.activeName=='d'){//全公司
- if(this.selectDataBox.type == 'user'){
- params.owner_id = this.selectDataBox.id;
- }else if(this.selectDataBox.type=='dept'){
- params.dept=this.selectDataBox.id;
- }
- }
- if(this.sortId){//状态
- params.composite_states=this.sortId==1? '1,2,3,4,5,7,8,9':'6';
- }
- if(this.dateParameter.cycle_type==2){
- params.quarter=this.dateParameter.dateId
- }
- if(this.dateParameter.cycle_type==3){
- params.half_year=this.dateParameter.dateId
- }
- if(this.dateParameter.cycle_type==4){
- params.month=this.dateParameter.dateId
- }
- this.$axiosUser('get', '/api/pro/okr/public/obj/list', params).then(res => {
- let list=res.data.data.list
- list.forEach(item=>{
- item.krs.forEach(e=>{
- e.currentRate=Number(e.process);
- e.process=Number(e.process)
- })
- })
- if (this.page === 1) {
- this.targetList = list
- } else {
- this.targetList = this.targetList.concat(list)
- }
- hasMore = list.length !== 10
- callback && callback(hasMore)
- })
- },
- // 上拉刷新
- refresh (done) {
- this.getList(false,done)
- },
- // 下拉加载
- infinite (done) {
- this.page++;
- this.getList(true,done)
- },
- getUnitList(){
- this.$axiosUser('get', '/api/pro/okr/public/kr/unit_list').then(res => {
- let data=res.data.data;
- data.reverse()
- this.$setCache('unitList',data)
- })
- },
- },
- created() {
- this.getUnitList();
- this.columns.forEach((e,index)=>{
- if(e.value==this.dateParameter.year){
- this.selectPftiTheEcho[0]=index
- }
- })
- this.tabs=[
- {title:'我的目标',name:'a',isShow:true},
- {title:'我的部门',name:'b',isShow:!this.$userInfo().is_okr_manager&&this.dept_list.length>0},
- {title:'关注的人',name:'c',isShow:true},
- {title:'全公司',name:'d',isShow:true},
- ]
- this.getList();
- },
- activated() {
- if(this.activeName=='c'){
- this.getGzUserList();
- }else{
- this.pullDown();
- }
- },
- };
- </script>
- <style scoped lang="less">
- .addUser{
- font-size: .6rem;
- padding: 0.2rem;
- border: 0.02rem dashed #89919f;
- text-align: center;
- height: 0.4rem;
- width: 0.4rem;
- line-height: .4rem;
- color: #89919f;
- border-radius: 2rem;
- }
- .userName{
- font-size: 0.28rem;
- width: 1rem;
- text-align: center;
- color: #89919F;
- }
- .userActive{
- background-color: #E9F0FD;
- }
- .userActive .userName{
- color: #26A2FF;
- }
- .selector {
- z-index: 1;
- display: flex;
- justify-content: center;
- width: 100%;
- height: 0.8rem;
- line-height: 0.8rem;
- background-color: #fff;
- text-align: center;
- font-size: 0.28rem;
- border-top: 1px solid #f1f1f1;
- i {
- margin: 0.23rem 0 0 0.1rem;
- color: #c3c3c3;
- }
- span {
- max-width: 3.5rem;
- overflow: hidden;
- }
- }
- .aite{
- width: 1rem;
- height: 1rem;
- text-align: center;
- line-height: 1rem;
- font-size: 0.6rem;
- cursor: pointer;
- color: #fff;
- display: inline-block;
- border-radius: 100%;
- background-color: #26A2FF;
- position: absolute;
- z-index: 2;
- bottom: 0.4rem;
- right: 0.4rem;
- }
- .progress {
- border-radius: 100px;
- background-color: #ebeef5;
- overflow: hidden;
- position: relative;
- vertical-align: middle;
- height: 0.2rem;
- width: 1rem;
- }
- .progress-inner {
- width: 0%;
- position: absolute;
- left: 0;
- top: 0;
- padding-top: 1px;
- height: 100%;
- background-image: linear-gradient(to right, #99BBFF 0%, #26A2FF 100%);
- border-radius: 100px;
- color: #fff;
- white-space: nowrap;
- transition: width 0.6s ease;
- }
- .bjYellow{
- background-image: linear-gradient(to right, #fedf86 0%, #FF9600 100%);
- }
- .bjRed{
- background-image: linear-gradient(to right, #FEA2A2 0%, #F16060 100%);
- }
- .huan{
- position: relative;
- width: 0.4rem;
- height: 0.4rem;
- border-radius: 100%;
- background-color: #E9F1FE;
- box-sizing: border-box;
- text-align: center;
- margin-right: 0.2rem;
- padding-top: 0.036rem;
- }
- .huan span{
- border: 2px solid #26A2FF;
- border-radius: 100%;
- width: 0.16rem;
- height: 0.16rem;
- display: inline-block;
- }
- .list-box{
- padding: 0.2rem;
- font-size: 0.32rem;
- background-color: #fff;
- border-radius: 5px;
- margin: 0 0.2rem;
- margin-bottom: 0.24rem;
- }
- .scroller{
- height: calc(100% - 2.75rem);
- position: relative;
- }
- .scroller2{
- height: calc(100% - 4.5rem);
- }
- .scroller3{
- height: calc(100% - 3.7rem);
- }
- .scroller4{
- height: calc(100% - 2.84rem);
- }
- .all {
- height: calc(100% - 0.92rem) !important;
- position: relative !important;
- }
- .search-box {
- border-radius: 25px;
- padding:0.1rem;
- border: 1px solid #f1f1f1;
- font-size: 0.28rem;
- }
- .header {
- background-color: #fff;
- padding: 0.2rem;
- font-size: 0.28rem;
- margin-bottom: 0.2rem;
- }
- .search-item{
- padding: 0.06rem 0.1rem;
- background-color: #F7F8FA;
- color: #89919F;
- width: 1.2rem;
- text-align: center;
- margin-right: 0.2rem;
- margin-bottom: 0.2rem;
- border-radius: 3px;
- font-size: 0.3rem;
- }
- .searchActive{
- color: #26A2FF;
- background-color: #E9F0FD;
- }
- .btn{
- background-color: #26A2FF;
- color: #fff;
- text-align: center;
- height: 0.8rem;
- line-height: 0.8rem;
- border-radius: 25px;
- }
- </style>
|