123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622 |
- <template>
- <div class="boxMinHeight">
- <div class="flex-box">
- <!-- 我的部门 -->
- <div style="width: 160px;background-color: #fff;border-radius: 10px;margin-right: 10px;padding: 20px 10px;height: calc(100vh - 80px);" v-if="myTargertType==4">
- <template v-if="userInfo.employee_detail.dept_list.length>0">
- <div style="margin-bottom:10px;font-size:16px;text-align: center;" class="blue cursor">
- <el-select v-model="dept_id" placeholder="请选择" class="selectUser" :clearable="false">
- <el-option v-for="item in dept_tree" :key="item.id" :label="item.name" :value="item.id"></el-option>
- </el-select>
- </div>
- <div style="height: calc(100vh - 160px);overflow-y:auto;" class="scroll-bar">
- <div class="flex-box-ce user-item" :class="ownerUserInfo.id==item.id? 'userActive':''" v-for="item in employeeOptions" :key="item.id" @click="ownerUserInfo=item">
- <userImage :id="item.id" width="36px" height="36px" fontSize="14" :user_name="item.name"></userImage>
- <Tooltip :preHtml="item.name">
- <div class="font-flex-word" style="margin-left: 10px;font-size: 14px;">{{ item.name }}</div>
- </Tooltip>
- </div>
- <div v-if="employeeOptions.length==0" style="text-align: center;margin-top: 30px;" class="fontColorC">暂无人员</div>
- <div style="height:30px"></div>
- </div>
- </template>
- <div class="fontColorC" v-else style="margin-top: 30px;text-align: center;">暂没有所属部门</div>
- </div>
- <div class="flex-1">
- <div class="flex-box-ce flex-d-center header">
- <div class="flex-1 flex-box-ce" style="max-width: 800px;">
- <template v-if="myTargertType==1">
- <div class="flex-box-ce" >
- <userImage :id="userInfo.id" width="50px" height="50px" :user_name="userInfo.name"></userImage>
- <span style="margin-left: 10px;font-size: 18px;font-weight: 700;color: #3F4755;">{{ userInfo.name }}</span>
- </div>
- <div class="flex-box-ce span-item" style="margin-left: 20px;">
- <span :class="idText=='owner_id'? 'spanActive':''" @click="idText='owner_id'">我负责的</span>
- <span :class="idText=='joiner_id'? 'spanActive':''" @click="idText='joiner_id'">我参与的</span>
- <span :class="idText=='publisher_id'? 'spanActive':''" @click="idText='publisher_id'">我创建的</span>
- </div>
- </template>
- <div v-if="myTargertType==2" style="font-size: 24px;font-weight: 600;padding: 9px 0;">公开项目</div>
- <div v-if="myTargertType==3" style="font-size: 24px;font-weight: 600;padding: 9px 0;">公司全部项目</div>
- <template v-if="myTargertType==4">
- <div class="flex-box-ce" >
- <userImage :id="ownerUserInfo.id" width="50px" height="50px" :user_name="ownerUserInfo.name"></userImage>
- <span style="margin-left: 10px;font-size: 18px;font-weight: 700;color: #3F4755;">{{ ownerUserInfo.name }}</span>
- </div>
- <div class="flex-box-ce span-item" style="margin-left: 20px;">
- <span :class="idText=='owner_id'? 'spanActive':''" @click="idText='owner_id'">Ta负责的</span>
- <span :class="idText=='joiner_id'? 'spanActive':''" @click="idText='joiner_id'">Ta参与的</span>
- <span :class="idText=='publisher_id'? 'spanActive':''" @click="idText='publisher_id'">Ta创建的</span>
- </div>
- </template>
- </div>
- <div class="flex-box-ce">
- <el-button type="primary" size="small" round style="margin-right: 10px;" @click="isShowAdd=true" v-if="myTargertType==1">创建项目</el-button>
- <el-input @input="keyinput" class="input" maxlength="20" prefix-icon="el-icon-search" style="width: 206px;" size="small" v-model="formData.keyword" clearable placeholder="请输入关键字" />
- <el-select class="select" size="small" v-model="formData.composite_state" placeholder="类型" style="width: 100px;">
- <el-option v-for="item in statusArr" :key="item.value" :label="item.label" :value="item.value"></el-option>
- </el-select>
- <div class="selectBox">
- <SelectProjectGj :formData="formData" :myTargertType="myTargertType" :idText="idText" @confirm="selectPeriodGjConfirm" ></SelectProjectGj>
- </div>
- </div>
- </div>
- <div v-loading="loading">
- <template v-if="projectList.length>0">
- <div class="itemBox" v-for="(item,index) in projectList" :key="item.id" @click="openDetail(item)">
- <div class="flex-box-ce flex-d-center">
- <div class="item-left flex-box">
- <div class="project-name clamp2">{{item.name}}</div>
- <div class="project-status" style="height: 22px;line-height: 22px;border-radius: 3px;padding: 0 5px;position: relative;top: 2px;font-size: 12px;background-color: #f1f1f1;">{{item.stateText}}</div>
- </div>
- <div class="fontColorB flex-box-ce" style="flex-shrink:0;">
- <div class="flex-box-ce">
- <svg-icon icon-class="#icon-biaoqian_wode" class="svgIcon" style="width: 1rem;height: 1rem;"></svg-icon>
- <span> {{item.userInfo.name}}</span>
- </div>
- <div class="flex-box-ce" style="margin-left: 30px;">
- <template v-if="item.day>30">
- <span>{{$moment(item.end_date).format('MM/DD')}}截止</span>
- </template>
- <template v-else>
- <span v-if="item.day>0" class="green">剩余{{item.day}}天</span>
- <span v-if="item.day==0" class="green">剩余1天</span>
- <span v-if="item.day<0&&item.composite_state != 4" class="red">逾期{{Math.abs(item.day)}}天</span>
- <span v-if="item.composite_state == 4">{{$moment(item.end_date).format('YY/MM/DD')}}截止</span>
- </template>
- <Progress :inputStyle="{ height: '14px', width: '140px', lineHeight: '14px' }" :status="item.composite_state==3? 3:1" :value="Number(item.process)" style="margin-left: 10px;"></Progress>
- </div>
- </div>
- </div>
- </div>
- <div style="text-align: center;background-color: #fff;padding:10px 0;border-radius: 10px;">
- <el-pagination layout="total,prev,pager,next,sizes" :current-page.sync="formData.page" :total="total"
- @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-sizes="[10, 20, 50, 100]"
- :page-size="formData.page_size"></el-pagination>
- </div>
- </template>
- <!-- 没有列表时 -->
- <div class="flex-box-v flex-center-center" style="height: 600px;" v-else>
- <noData isSolt imgUrl="static/images/no_data.png" imgW="150px" imgH="100px">
- <div v-if="myTargertType==1" style="text-align: center;margin: 0 0;line-height: 30px;">暂无项目,去<span @click="isShowAdd=true" class="blue cursor">创建项目</span></div>
- <div v-else style="text-align: center;margin: 0 0;line-height: 30px;">暂无项目</div>
- </noData>
- </div>
- </div>
- </div>
- </div>
- <AddProject :visible.sync="isShowAdd" @confirm="ActiveAddProject"></AddProject>
- </div>
- </template>
- <script>
- import Tooltip from '@/components/Tooltip'; //鼠标悬浮显示文字
- import { _debounce} from '@/utils/auth';
- import EmployeeSelector from '@/components/EmployeeSelector';
- import SelectProjectGj from '@/okr/components/project/SelectProjectGj'; //
- import AddProject from '@/okr/components/project/AddProject'; //
- import Progress from '@/okr/components/public/Progress'; //进度条
- export default {
- name: 'myProject',
- components: {EmployeeSelector,Tooltip,SelectProjectGj,AddProject,Progress},
- props:{
- myTargertType:{ //从不同页面加载 1:我的项目 2:公开项目 3全部项目 4我的部门
- type:Number,
- default:1
- }
- },
- data() {
- return {
- userInfo: this.$userInfo(),
- isShowAdd: false,
- idText: 'owner_id',
- projectList:[],
- loading: false,
- total: 0,
- formData: {
- page: 1,
- page_size: 10,
- dateTime:[],
- owner_id:'',// 否 string 负责人id 默认为0
- joiner_id:'',// 否 string 参与者id 默认为0
- publisher_id:'',// 否 string 发布者id 默认为0
- scope_type:0,// 否 string 可见范围 1-相关人员可见 2-全员可见 默认为0不区分
- composite_state:0,// 否 strin g 综合状态 1-未开始 2-进行中 3-逾期 4-达标 默认为0不区分
- dept_id:'',// 否 string 部门id,默认为0
- start_date:'',// 否 string 开始日期 格式:2024-01-01 默认为空字符串
- end_date:'',// 否 string 结束日期 格式:2024-01-01 默认为空字符串
- sort:'ct_desc',// 否 string 排序 ct_asc-创建时间正序 ct_desc-创建时间倒序 up_asc-更新时间正序 up_desc-更新时间倒序 默认为ct_desc
- keyword:'',// 否 string 关键字
- },
- statusArr: [
- {value: 0,label: '全部状态'},
- {value: 1,label: '未开始'},
- {value: 2,label: '进行中'},
- {value: 3,label: '已逾期'},
- {value: 4,label: '已完成'},
- ],
- // 我的部门相关
- dept_id:'',
- employeeOptions:[],
- ownerUserInfo:{},
- dept_tree:[],
- };
- },
- watch: {
- 'formData.composite_state'(){
- this.getProjectList();
- },
- ownerUserInfo(val){
- this.getProjectList();
- },
- idText(){
- this.getProjectList();
- },
- dept_id(){
- this.get_employee_list();
- },
- },
- methods: {
- get_employee_list() {
- this.$axiosUser('get', '/api/pro/employee/list', { dept_id: this.dept_id,page:1,page_size:1000,include_sub:0},'v2').then(res => {
- this.employeeOptions = res.data.data.list;
- if(this.employeeOptions.length>0){
- this.ownerUserInfo=this.employeeOptions[0];
- }
- });
- },
- openDetail(item){
- this.$router.push({path:'/projectDetail',query:{id:item.id}})
- },
- keyinput:_debounce(function(val) {
- this.getProjectList();
- }),
- ActiveAddProject(){
- this.getProjectList();
- },
- getProjectList(is){
- is? '':this.formData.page=1;
- let data={
- page:is? this.formData.page:1,
- page_size:this.formData.page_size,
- scope_type:0,// 否 string 可见范围 1-相关人员可见 2-全员可见 默认为0不区分
- composite_state:this.formData.composite_state,// 否 strin g 综合状态 1-未开始 2-进行中 3-逾期 4-达标 默认为0不区分
- dept_id:this.formData.dept_id? this.formData.dept_id[this.formData.dept_id.length-1]:0,// 否 string 部门id,默认为0
- sort:this.formData.sort,// 否 string 排序 ct_asc-创建时间正序 ct_desc-创建时间倒序 up_asc-更新时间正序 up_desc-更新时间倒序 默认为ct_desc
- keyword:this.formData.keyword,// 否 string 关键字
- }
- if(this.formData.owner_id){
- data.owner_id=this.formData.owner_id
- }
- if(this.formData.joiner_id){
- data.joiner_id=this.formData.joiner_id
- }
- if(this.myTargertType==1){
- if(this.idText=='owner_id'){
- data.owner_id=this.$userInfo().id;
- }
- if(this.idText=='joiner_id'){
- data.joiner_id=this.$userInfo().id;
- }
- if(this.idText=='publisher_id'){
- data.publisher_id=this.$userInfo().id;
- }
- }else if(this.myTargertType==2){//公开项目
- data.scope_type=2
- }else if(this.myTargertType==3){//公司项目
- data.scope_type=0
- }else if(this.myTargertType==4){//部门项目
- if(this.idText=='owner_id'){
- data.owner_id=this.ownerUserInfo.id;
- }
- if(this.idText=='joiner_id'){
- data.joiner_id=this.ownerUserInfo.id;
- }
- if(this.idText=='publisher_id'){
- data.publisher_id=this.ownerUserInfo.id;
- }
- }
- if(this.formData.dateTime&&this.formData.dateTime.length>0){
- data.start_date=this.formData.dateTime[0];// 否 string 开始日期 格式:2024-01-01 默认为空字符串
- data.end_date=this.formData.dateTime[1];// 否 string 结束日期 格式:2024-01-01 默认为空字符串
- }
- this.loading = true;
- this.$axiosUser('get','api/pro/okr/project/list',data).then(res => {
- let list=res.data.data.list;
- list.forEach(item=>{
- item.userInfo=this.$getEmployeeMapItem(item.owner_id);
- item.stateText=this.returnStatus(item.composite_state);
- item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
- })
- this.projectList=list;
- this.total=res.data.data.total;
- }).finally(()=>{
- this.loading = false;
- })
- },
- returnStatus(index){
- let arr=['未开始','进行中','已逾期','已完成'];
- return arr[index-1];
- },
- selectPeriodGjConfirm(data){
- this.formData.sort = data.sort;
- this.formData.owner_id = data.owner_id;
- this.formData.joiner_id = data.joiner_id;
- this.formData.dateTime = data.dateTime;
- this.formData.dept_id = data.dept_id;
- this.getProjectList();
- },
- handleSizeChange(val) {
- this.formData.page=1;
- this.formData.page_size = val;
- this.getProjectList();
- },
- // 页面跳转
- handleCurrentChange(val) {
- this.formData.page = val;
- this.getProjectList(true);
- },
- },
- created() {
- if(this.myTargertType==2||this.myTargertType==3){
- this.idText='';
- }
- if(this.myTargertType==4){
- let dept_tree=[];
- this.userInfo.employee_detail.manage_dept_ids.forEach(id=>{
- dept_tree.push(this.$getDept(id));
- })
- this.dept_tree=dept_tree;
- this.$nextTick(()=>{
- if(dept_tree.length>0){
- this.dept_id=dept_tree[0].id
- }
- })
- }
- },
- mounted() {
- if(this.myTargertType==1){
- this.getProjectList();
- }
- },
- };
- </script>
- <style scoped lang="scss">
- .project-name{
- font-size: 18px;
- font-weight: 550;
- color: rgb(20, 28, 40);
- max-width: 700px;
- padding-right: 6px;
- }
- .width-120 {
- width: 100px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .selectUser ::v-deep input {
- border-radius: 20px;
- }
- .user-item {
- padding: 4px 6px;
- border-radius: 5px;
- cursor: pointer;
- }
- .userActive {
- background-color: #ecf5ff;
- color: #409EFF;
- }
- .span-item span {
- font-size: 14px;
- padding: 8px 20px;
- border-bottom: 2px solid #f1f1f1;
- // border-radius: 3px;
- color: #89919f;
- cursor: pointer;
- }
- .spanActive {
- border-bottom: 2px solid #409EFF !important;
- color: #409EFF !important;
- }
- .okrs-box {
- padding: 10px 0;
- border-bottom: 1px solid #f1f1f1;
- cursor: pointer;
- }
- .okrs-box:hover {
- background-color: #f4f6f9;
- }
- .message-items {
- margin-top: 10px;
- font-size: 12px;
- }
- .message-items div {
- margin-right: 20px;
- cursor: pointer;
- }
- .message-items i {
- padding-right: 5px;
- }
- .weight {
- width: 90px;
- margin-right: 5px;
- padding: 5px;
- border: 1px dotted #fff;
- border-radius: 5px;
- cursor: pointer;
- }
- .weight:hover {
- border: 1px dotted #ccc;
- }
- .weight span {
- display: inline-block;
- width: 50px;
- text-align: center;
- color: #e6a23c;
- }
- .kr-item {
- padding: 4px 0;
- position: relative;
- margin-bottom: 8px;
- border-radius: 5px;
- }
- .kr-item:hover {
- background-color: #f4f6f9;
- }
- .huan {
- position: relative;
- width: 24px;
- height: 24px;
- border-radius: 100%;
- background-color: #E9F1FE;
- box-sizing: border-box;
- margin: 0 3px;
- text-align: center;
- line-height: 25px;
- }
- .huan span {
- border: 2px solid #409EFF;
- border-radius: 100%;
- width: 12px;
- height: 12px;
- display: inline-block;
- }
- .add-task-title {
- padding: 10px;
- position: relative;
- }
- .add-task-title::after {
- content: "";
- position: absolute;
- width: 4px;
- height: 14px;
- border-radius: 5px;
- background-color: #409EFF;
- left: 0;
- top: 13px;
- }
- .inputDc {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- bottom: 0;
- z-index: 9;
- cursor: pointer;
- }
- .el-icon-more {
- width: 20px;
- height: 20px;
- box-sizing: border-box;
- text-align: center;
- line-height: 20px;
- cursor: pointer;
- }
- .el-icon-more:hover {
- background-color: #606266;
- border-radius: 25px;
- color: #fff;
- }
- .border {
- -webkit-appearance: none;
- background-color: #fff;
- background-image: none;
- border-radius: 4px;
- border: 1px solid #dcdfe6;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- color: #C0C4CF;
- font-size: inherit;
- height: auto;
- outline: 0;
- padding: 0 15px;
- padding-right: 10px;
- line-height: 34px;
- width: 270px;
- position: relative;
- cursor: pointer;
- }
- .border .font-flex-word {
- color: #606266;
- }
- .border:hover {
- border: 1px solid #c0c4cc;
- }
- .add-task-item {
- position: relative;
- }
- .add-task-item:hover i {
- cursor: pointer;
- opacity: 1 !important;
- }
- .add-task {
- // padding-left: 30px;
- }
- .oBox {
- box-shadow: 0 0px 10px #F0F4FA;
- border-radius: 3px;
- padding: 5px 8px;
- }
- .add-task ::v-deep input {
- border: none;
- padding-right: 80px;
- }
- .oBox ::v-deep input {
- border: none;
- font-size: 18px;
- font-weight: 600;
- color: #141c28;
- padding-right: 80px;
- }
- .oBox ::v-deep input::-webkit-input-placeholder {
- font-weight: 500;
- }
- .edit {
- display: none;
- position: relative;
- top: 1px;
- padding-left: 5px;
- transition: all .3s;
- }
- .edit:hover {
- color: #409EFF !important;
- }
- .selectBox {
- background-color: #fff;
- border-radius: 25px;
- padding: 10px 20px;
- padding-left: 0;
- }
- .header {
- margin-bottom: 10px;
- border-radius: 10px;
- padding: 10px;
- background-color: #fff;
- }
- .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;
- }
- .jt {
- width: 24px;
- position: relative;
- top: 2px;
- left: 4px;
- transform: rotateY(180deg);
- margin-left: 0px;
- }
- .itemBox {
- padding: 20px;
- border-radius: 10px;
- background-color: #fff;
- margin-bottom: 10px;
- box-shadow: 0 2px 12px #EBF0F6;
- cursor: pointer;
- }
- ::v-deep .el-tabs__item {
- color: #89919f;
- }
- ::v-deep .is-active {
- color: #409EFF;
- font-weight: 600;
- }
- ::v-deep .el-tabs__nav .is-active {
- font-size: 16px;
- }
- ::v-deep .el-tabs__header {
- margin: 0px;
- }
- .select {
- margin-right: 6px;
- }
- .select ::v-deep .el-input__inner {
- border-radius: 25px;
- }
- .input ::v-deep .el-input__inner {
- border: none;
- border-bottom: 1px solid #f1f1f1;
- border-radius: 0px;
- }
- </style>
|