506 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <section class="AppConsole">
 | |
|     <el-row type="flex" class="header-text">
 | |
|       <el-row style="width: 392px" type="flex" align="middle">
 | |
|         <i class="iconfont iconDate1"/>
 | |
|         <span v-text="`今天是 ${$moment().format('YYYY年M月D日 dddd')}`"/>
 | |
|       </el-row>
 | |
|       <el-row type="flex" align="middle" class="notice fill">
 | |
|         <el-button type="primary" icon="iconfont iconNotice">通知公告</el-button>
 | |
|         <div class="notice-content nowarp-text fill">
 | |
|           <el-carousel ref="noticeCarousel" height="32px" direction="vertical" indicator-position="none">
 | |
|             <template v-if="noticeList.length">
 | |
|               <el-carousel-item v-for="(notice,i) in noticeList" :key="i">
 | |
|                 <div style="text-align: left">{{ notice.title }}</div>
 | |
|               </el-carousel-item>
 | |
|             </template>
 | |
|             <el-carousel-item v-else style="text-align: left">暂无通知</el-carousel-item>
 | |
|           </el-carousel>
 | |
|         </div>
 | |
|         <el-button type="text" style="color:rgba(153,153,153,1)" @click="$router.push({name:'通知公告'})">更多</el-button>
 | |
|         <el-button type="text" style="color:rgba(153,153,153,1);margin-left: 0;padding: 8px 0"
 | |
|                    icon="iconfont iconTriangle_Up" @click="$refs.noticeCarousel.prev()"></el-button>
 | |
|         <el-button type="text" style="color:rgba(153,153,153,1);margin-left: 0;padding: 8px 8px 8px 0"
 | |
|                    icon="iconfont iconTriangle_Down" @click="$refs.noticeCarousel.next()"></el-button>
 | |
|       </el-row>
 | |
|     </el-row>
 | |
|     <div class="main-console">
 | |
|       <el-row type="flex">
 | |
|         <!--用户信息卡片-->
 | |
|         <div class="card-panel userinfo-panel">
 | |
|           <el-row type="flex" class="top-panel" align="middle">
 | |
|             <div class="avatar">
 | |
|               <el-avatar :size="64" :src="user.info.avatar">
 | |
|                 {{ defaultAvatar }}
 | |
|               </el-avatar>
 | |
|             </div>
 | |
|             <el-row type="flex" justify="space-between" align="middle">
 | |
|               <div class="basic-info">
 | |
|                 {{ $moment().format("A") + "好," + user.info.name }}
 | |
|                 <br>{{ welcomeWord() }}
 | |
|               </div>
 | |
|               <el-button type="text" @click="$router.push({name:'个人中心'})">
 | |
|                 个人中心 <i class="iconfont iconArrow_Right"/></el-button>
 | |
|             </el-row>
 | |
|           </el-row>
 | |
|           <div class="user-info-panel">
 | |
|             <li>
 | |
|               <div>所属单位</div>
 | |
|               {{ user.info.unitName }}
 | |
|             </li>
 | |
|             <li>
 | |
|               <div>当前职务</div>
 | |
|               {{ user.info.position }}
 | |
|             </li>
 | |
|             <li>
 | |
|               <div>所属党组织</div>
 | |
|               {{ user.info.organizationName }}
 | |
|             </li>
 | |
|             <li>
 | |
|               <div>上次登录</div>
 | |
|               <span style="color: #2266ff">{{ user.info.lastLoginTime }}</span></li>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div class="fill mar-l20 topLeft">
 | |
|           <el-row type="flex" justify="space-between">
 | |
|             <div class="data-panel-area">
 | |
|               <div class="card-panel data-panel" @click="$router.push({name:'待办事项'})">
 | |
|                 <div class="item-label">
 | |
|                   <svg class="icon" aria-hidden="true">
 | |
|                     <use xlink:href="#iconBacklog"></use>
 | |
|                   </svg>
 | |
|                   <div style="margin-left: 8px">待办事项</div>
 | |
|                 </div>
 | |
|                 <b style="font-size: 20px">{{ todoTotal }}</b>
 | |
|               </div>
 | |
|             </div>
 | |
|             <div class="data-panel-area">
 | |
|               <div class="card-panel data-panel" @click="$router.push({name:'消息中心'})">
 | |
|                 <div class="item-label">
 | |
|                   <svg class="icon" aria-hidden="true">
 | |
|                     <use xlink:href="#iconUnread_message"></use>
 | |
|                   </svg>
 | |
|                   <div style="margin-left: 8px">未读消息</div>
 | |
|                 </div>
 | |
|                 <b style="font-size: 20px">{{ msgTotal }}</b>
 | |
|               </div>
 | |
|             </div>
 | |
|             <div class="data-panel-area">
 | |
|               <div class="card-panel data-panel"
 | |
|                    @click="$router.push({name:'33',query:{listType: 1,meetingStatus: 1}})">
 | |
|                 <div class="item-label">
 | |
|                   <svg class="icon" aria-hidden="true">
 | |
|                     <use xlink:href="#iconAttend_The_Meeting"></use>
 | |
|                   </svg>
 | |
|                   <div style="margin-left: 8px">待参加会议</div>
 | |
|                 </div>
 | |
|                 <b style="font-size: 20px">{{ conferenceTotal }}</b>
 | |
|               </div>
 | |
|             </div>
 | |
|           </el-row>
 | |
|           <ai-card title="待办事项" class="mar-t20 fill">
 | |
|             <template #content>
 | |
|               <el-row type="flex">
 | |
|                 <el-col :span="3" class="todo-item" v-for="(todo,i) in todoList" :key="i"
 | |
|                         @click.native="$router.push({name:$dict.getLabel('todoFrom',todo.type),query:$dict.getLabel('todoParams',todo.type)})">
 | |
|                   <div style="width: 48px;margin: 8px auto 0">
 | |
|                     <el-badge type="warning" :value="todo.count">
 | |
|                       <svg class="icon" aria-hidden="true">
 | |
|                         <use :xlink:href="$dict.getLabel('todoIcon',todo.type)"></use>
 | |
|                       </svg>
 | |
|                     </el-badge>
 | |
|                   </div>
 | |
|                   <div class="item-label">{{ $dict.getLabel("todoFrom", todo.type) }}</div>
 | |
|                 </el-col>
 | |
|               </el-row>
 | |
|             </template>
 | |
|           </ai-card>
 | |
|         </div>
 | |
|       </el-row>
 | |
|       <el-row type="flex" class="conference-and-message">
 | |
|         <ai-card title="未读消息" class="fill">
 | |
|           <template #right>
 | |
|             <el-button type="text" @click="$router.push({name:'消息中心'})">消息中心<i class="iconfont iconArrow_Right"/></el-button>
 | |
|           </template>
 | |
|           <template #content>
 | |
|             <div class="unread-message-list">
 | |
|               <li v-for="(msg,i) in msgList" :key="i" class="nowarp-text">
 | |
|                 <div class="list-type"> </div>
 | |
|                 <div style="width: calc(100% - 16px)">
 | |
|                   <p class="nowarp-text">{{ msg.content }}</p>
 | |
|                   <span style="color: #26f" v-text="`[${msg.title}]`"/><span style="color:#999" v-text="msg.receiveTime"/>
 | |
|                 </div>
 | |
|               </li>
 | |
|               <ai-empty v-if="!msgList.length">暂无消息</ai-empty>
 | |
|             </div>
 | |
|           </template>
 | |
|         </ai-card>
 | |
|         <ai-card title="我的会议" class="fill">
 | |
|           <template #right>
 | |
|             <el-button type="text" @click="$router.push({name:'33'})">更多会议<i class="iconfont iconArrow_Right"/></el-button>
 | |
|           </template>
 | |
|           <template #content>
 | |
|             <div class="conference-list">
 | |
|               <li v-for="(item,i) in conferenceList" :key="i" @click="$router.push({name:'33',query:{listType: 1,meetingStatus: 1,confirmStatus:1}})">
 | |
|                 <div class="list-type"></div>
 | |
|                 <div>
 | |
|                   <span>{{ item.title }}</span><br>
 | |
|                   <span
 | |
|                       style="color:#999">{{
 | |
|                       [$moment(item.startTime).format("YYYY-MM-DD hh:mm"), item.address].join(" ")
 | |
|                     }}</span>
 | |
|                 </div>
 | |
|               </li>
 | |
|             </div>
 | |
|             <ai-empty v-if="!conferenceList.length">暂无会议</ai-empty>
 | |
|           </template>
 | |
|         </ai-card>
 | |
|       </el-row>
 | |
|     </div>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import {mapState} from "vuex";
 | |
| 
 | |
| export default {
 | |
|   name: "AppConsole",
 | |
|   label: "工作台",
 | |
|   computed: {
 | |
|     ...mapState(['user']),
 | |
|     defaultAvatar() {
 | |
|       return this.user.info.name?.slice(-2) || "游客"
 | |
|     }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       todoList: [],
 | |
|       todoTotal: 0,
 | |
|       msgList: [],
 | |
|       msgTotal: 0,
 | |
|       conferenceList: [],
 | |
|       conferenceTotal: 0,
 | |
|       noticeList: []
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     getTodoList() {
 | |
|       this.$request.post("/message/systodolist/type-count").then(res => {
 | |
|         this.todoList = res.data.list
 | |
|         this.todoTotal = res.data.total
 | |
|       })
 | |
|     },
 | |
|     getUnreadMessage() {
 | |
|       this.$request.post("/message/appmessage/list", null, {
 | |
|         params: {readStatus: 0}
 | |
|       }).then(res => {
 | |
|         this.msgList = res.data.records
 | |
|         this.msgTotal = res.data.total
 | |
|       })
 | |
|     },
 | |
|     getConferences() {
 | |
|       this.$request.post("/app/appmeetinginfo/list", null, {
 | |
|         params: {listType: 1, meetingStatus: 1}
 | |
|       }).then(res => {
 | |
|         this.conferenceList = res.data.records
 | |
|         this.conferenceTotal = res.data.total
 | |
|       })
 | |
|     },
 | |
|     getNotice() {
 | |
|       this.$request.post("/app/appannouncement/list-latest", null, {
 | |
|         params: {
 | |
|           areaId: this.user.info.areaId,
 | |
|           current: 1,
 | |
|           size: 3
 | |
|         }
 | |
|       }).then(res => {
 | |
|         this.noticeList = res.data.records
 | |
|       })
 | |
|     },
 | |
|     welcomeWord() {
 | |
|       let word = "", hour = this.$moment().hour()
 | |
|       if (hour < 6) {
 | |
|         word = "你来的似乎有点早~"
 | |
|       } else if (hour < 9) {
 | |
|         word = "又是愉快的一天!"
 | |
|       } else if (hour < 12) {
 | |
|         word = "好好工作!"
 | |
|       } else if (hour < 14) {
 | |
|         word = "养精蓄锐,以逸待劳!"
 | |
|       } else if (hour < 17) {
 | |
|         word = "欢迎回来!"
 | |
|       } else if (hour < 19) {
 | |
|         word = "要按时下班哦~"
 | |
|       } else if (hour < 22) {
 | |
|         word = "忙碌了一天,注意休息~"
 | |
|       } else {
 | |
|         word = "夜深了,该休息了~"
 | |
|       }
 | |
|       return word;
 | |
|     }
 | |
|   },
 | |
|   create() {
 | |
|     this.$dict.load("todoFrom", "todoIcon", "todoParams")
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| <style lang="scss" scoped>
 | |
| .icon {
 | |
|   width: 1em;
 | |
|   height: 1em;
 | |
|   vertical-align: -0.15em;
 | |
|   fill: currentColor;
 | |
|   overflow: hidden;
 | |
| }
 | |
| 
 | |
| .AppConsole {
 | |
|   .header-text {
 | |
|     font-weight: normal;
 | |
|     color: #333333;
 | |
|     padding: 0 calc(50% - 580px);
 | |
|     background: #fff;
 | |
| 
 | |
| 
 | |
|     span {
 | |
|       font-size: 14px;
 | |
|       margin-left: 8px;
 | |
|     }
 | |
| 
 | |
|     .notice {
 | |
|       margin: 8px auto;
 | |
|       background: rgba(247, 247, 247, 1);
 | |
|       border-radius: 2px;
 | |
|       border: 1px solid rgba(221, 221, 221, 1);
 | |
|       text-align: center;
 | |
|       height: 32px;
 | |
|       font-size: 14px;
 | |
| 
 | |
|       .label {
 | |
|         padding: 0 8px;
 | |
|         min-width: 112px;
 | |
|         color: white;
 | |
|         background: rgba(34, 102, 255, 1);
 | |
|         border-radius: 2px 0 0 2px;
 | |
|         line-height: 32px;
 | |
|         box-sizing: border-box;
 | |
|       }
 | |
| 
 | |
|       .notice-content {
 | |
|         padding: 0 8px;
 | |
|         color: rgba(51, 51, 51, 1);
 | |
|         line-height: 32px;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .topLeft {
 | |
|     display: flex;
 | |
|     flex-direction: column;
 | |
| 
 | |
|     .ai-card:last-of-type {
 | |
|       margin-bottom: 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .main-console {
 | |
|     height: calc(100% - 92px);
 | |
|     padding: 20px 20px 24px;
 | |
|     width: 1200px;
 | |
|     margin: auto;
 | |
| 
 | |
|     .userinfo-panel {
 | |
|       min-width: 372px;
 | |
| 
 | |
|       .top-panel {
 | |
|         padding: 0 16px;
 | |
|         background-image: url("./assets/bg_prolife.png");
 | |
|         background-size: 100%;
 | |
|         background-repeat: no-repeat;
 | |
| 
 | |
|         :deep( .avatar ){
 | |
|           padding: 8px;
 | |
|           width: initial;
 | |
|           height: initial;
 | |
|           border-radius: 50%;
 | |
|           border: 2px solid rgba(34, 102, 255, 0.5);
 | |
|           background: white;
 | |
|           font-size: 24px;
 | |
|           box-sizing: border-box;
 | |
|           margin-right: 8px;
 | |
|           display: flex;
 | |
|           align-items: center;
 | |
|           justify-content: center;
 | |
| 
 | |
|           img {
 | |
|             width: 100%;
 | |
|           }
 | |
| 
 | |
|           .el-avatar:hover {
 | |
|             animation: rotate 15s ease-in-out;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         .basic-info {
 | |
|           font-size: 16px;
 | |
|           color: rgba(51, 51, 51, 1);
 | |
|           line-height: 24px;
 | |
|           margin: 36px 0;
 | |
|         }
 | |
| 
 | |
|         .el-row {
 | |
|           flex: 1;
 | |
|           min-width: 0;
 | |
| 
 | |
|           .el-button {
 | |
|             color: #999;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       .user-info-panel {
 | |
|         padding: 24px;
 | |
| 
 | |
|         li {
 | |
|           font-size: 14px;
 | |
|           line-height: 19px;
 | |
|           margin-bottom: 8px;
 | |
|           display: flex;
 | |
| 
 | |
|           div {
 | |
|             width: 94px;
 | |
|             color: rgba(102, 102, 102, 1);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .card-panel {
 | |
|       background: rgba(255, 255, 255, 1);
 | |
|       box-shadow: 0 16px 32px 0 rgba(0, 0, 0, 0.02);
 | |
|       border-radius: 4px;
 | |
|     }
 | |
| 
 | |
|     .todo-item {
 | |
|       background: rgba(243, 246, 249, 0);
 | |
|       border-radius: 4px;
 | |
|       cursor: pointer;
 | |
| 
 | |
|       svg {
 | |
|         height: 48px;
 | |
|         width: 48px;
 | |
|       }
 | |
| 
 | |
|       .item-label {
 | |
|         color: #333;
 | |
|         text-align: center;
 | |
|         font-size: 14px;
 | |
|         line-height: 32px
 | |
|       }
 | |
| 
 | |
|       &:hover {
 | |
|         background: rgba(239, 246, 255, 1);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .data-panel-area:hover > .data-panel {
 | |
|       transform: translateY(-2px);
 | |
|       box-shadow: 0 16px 32px -16px rgba(36, 103, 255, 0.3);
 | |
|     }
 | |
| 
 | |
|     .data-panel {
 | |
|       width: 224px;
 | |
|       height: 80px;
 | |
|       background: rgba(255, 255, 255, 1);
 | |
|       border-radius: 4px;
 | |
|       display: flex;
 | |
|       justify-content: space-between;
 | |
|       padding: 0 16px;
 | |
|       line-height: 80px;
 | |
|       cursor: pointer;
 | |
| 
 | |
|       svg {
 | |
|         margin: 29px 0;
 | |
|         width: 24px;
 | |
|         height: 24px;
 | |
|       }
 | |
| 
 | |
|       .item-label {
 | |
|         display: flex;
 | |
|         font-size: 14px;
 | |
|       }
 | |
| 
 | |
|       b {
 | |
|         font-size: 20px;
 | |
|         color: rgba(51, 51, 51, 1);
 | |
|         font-family: Arial, serif;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .conference-and-message {
 | |
|       height: calc(100% - 296px);
 | |
|       margin-top: 20px;
 | |
|       gap: 20px;
 | |
|     }
 | |
| 
 | |
|     .unread-message-list {
 | |
|       height: calc(100% - 48px);
 | |
|       overflow-y: auto;
 | |
|       overflow-x: hidden;
 | |
| 
 | |
|       .list-type {
 | |
|         width: 5px;
 | |
|         height: 5px;
 | |
|         border-radius: 50%;
 | |
|         border: 3px solid #26f;
 | |
|         margin: 4px 8px;
 | |
|       }
 | |
| 
 | |
|       li {
 | |
|         display: flex;
 | |
|         font-size: 14px;
 | |
|         margin: 0 16px;
 | |
|         padding: 15px 8px;
 | |
|         line-height: 19px;
 | |
| 
 | |
|         &:hover {
 | |
|           background: rgba(239, 246, 255, 1);
 | |
|         }
 | |
|       }
 | |
| 
 | |
|     }
 | |
| 
 | |
|     .conference-list {
 | |
|       height: calc(100% - 48px);
 | |
|       overflow-y: auto;
 | |
| 
 | |
|       .list-type {
 | |
|         width: 2px;
 | |
|         height: 40px;
 | |
|         background: rgba(255, 136, 34, 1);
 | |
|         border-radius: 2px;
 | |
|         margin-right: 14px;
 | |
|       }
 | |
| 
 | |
|       li {
 | |
|         display: flex;
 | |
|         font-size: 14px;
 | |
|         margin: 0 16px;
 | |
|         padding: 15px 8px;
 | |
|         line-height: 19px;
 | |
|         cursor: pointer;
 | |
| 
 | |
|         &:hover {
 | |
|           background: rgba(239, 246, 255, 1);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| @keyframes rotate {
 | |
|   to {
 | |
|     transform: rotate(60turn);
 | |
|   }
 | |
| }
 | |
| </style>
 |