| <template> | 
|   <div class="common-header"> | 
|     <div class="header"> | 
|       <div class="logo"> | 
|         <div class="title">{{ title }}</div> | 
|         <div class="list"> | 
|             <div  :class="index==currentIndex?'item active':'item'" v-for="(item,index) in topMenuList.list" :key="item.id"  @click="getHeaderNav(item,index)" :index="index">{{item.label}} | 
|               <div v-if="index==currentIndex" class="linellae"></div> | 
|             </div> | 
|         </div> | 
|       </div> | 
|       <div class="user"> | 
|         <el-dropdown v-if="isLogined" trigger="click"> | 
|           <span class="el-dropdown-link"> | 
|             <!-- <img v-if="userInfo != null" :src="userInfo.avatar == null ? `${require('@/assets/avatar/man.png')}` : userInfo.avatar" alt="">{{userInfo | displayName}}<i class="el-icon-arrow-down el-icon--right"></i> --> | 
|             <img v-if="userInfo != null" style="width: 30px !important" src="@/assets/avatar/man.png" alt="" />{{ | 
|               userInfo | displayName | 
|             }}<i class="el-icon-arrow-down el-icon--right"></i> | 
|           </span> | 
|           <el-dropdown-menu slot="dropdown"> | 
|             <el-dropdown-item @click.native="changePwd">修改密码</el-dropdown-item> | 
|             <el-dropdown-item @click.native="logout">退出登录</el-dropdown-item> | 
|           </el-dropdown-menu> | 
|         </el-dropdown> | 
|       </div> | 
|     </div> | 
|     <!-- 修改密码 --> | 
|     <GlobalAlertWindow title="修改密码" :visible.sync="visible.changePwd" | 
|       :showClose="userInfo && (!userInfo.needChangePwd || userInfo.needChangePwd == '0')" | 
|       :showCancel="userInfo && (!userInfo.needChangePwd || userInfo.needChangePwd == '0')" @confirm="confirmChangePwd" | 
|       @close="visible.changePwd = false"> | 
|       <el-form :model="changePwdData.form" ref="changePwdDataForm" :rules="changePwdData.rules"> | 
|         <el-form-item label="原始密码" prop="oldPwd" required> | 
|           <el-input v-model="changePwdData.form.oldPwd" type="password" placeholder="请输入原始密码" maxlength="30" | 
|             show-password></el-input> | 
|         </el-form-item> | 
|         <el-form-item label="新密码" prop="newPwd" required> | 
|           <el-input v-model="changePwdData.form.newPwd" type="password" placeholder="请输入新密码,至少包括数字、大写字母、小写字母、特殊字符中的三种字符,且至少8位数" | 
|             maxlength="20" show-password></el-input> | 
|         </el-form-item> | 
|         <!-- <div style="font-size: 12px;color:#999999">密码需包含字母、数字及特殊字符中的至少两种</div> --> | 
|         <el-form-item label="确认新密码" prop="confirmPwd" required> | 
|           <el-input v-model="changePwdData.form.confirmPwd" type="password" placeholder="请再次输入新密码" maxlength="20" | 
|             show-password></el-input> | 
|         </el-form-item> | 
|       </el-form> | 
|     </GlobalAlertWindow> | 
|   </div> | 
| </template> | 
|   | 
| <script> | 
| import { mapState, mapMutations } from 'vuex' | 
| import GlobalAlertWindow from './GlobalAlertWindow' | 
| import { logout, updatePwd } from '@/api/system/common' | 
| import { getAppHeaderNav } from '@/api' | 
| export default { | 
|   name: 'CommonHeader', | 
|   components: { GlobalAlertWindow }, | 
|   props: { | 
|     isLogined: { | 
|       type: Boolean, | 
|       default: true | 
|     } | 
|   }, | 
|   data () { | 
|     return { | 
|       title: process.env.VUE_APP_TITLE, | 
|       headerNavData: {}, | 
|       currentIndex: 0, | 
|       visible: { | 
|         // 修改密码 | 
|         changePwd: false | 
|       }, | 
|       isWorking: { | 
|         // 修改密码 | 
|         changePwd: false | 
|       }, | 
|       username: 'bob', // 用户名 | 
|       // 修改密码弹框 | 
|       changePwdData: { | 
|         form: { | 
|           oldPwd: '', | 
|           newPwd: '', | 
|           confirmPwd: '' | 
|         }, | 
|         rules: { | 
|           oldPwd: [ | 
|             { required: true, message: '请输入原始密码' } | 
|           ], | 
|           newPwd: [ | 
|             { required: true, message: '请输入密码', trigger: 'blur' }, | 
|             { validator: this.validatePassword, trigger: 'blur' } | 
|           ], | 
|           confirmPwd: [ | 
|             { required: true, message: '请再次输入新密码' } | 
|           ] | 
|         } | 
|       } | 
|     } | 
|   }, | 
|   computed: { | 
|     ...mapState(['menuData', 'userInfo', 'topMenuList']) | 
|     // title () { | 
|     //   return this.$route.meta.title | 
|     // } | 
|   }, | 
|   created () { | 
|   | 
|   }, | 
|   mounted () { | 
|     // needChangePwd 0 : 默认密码需要修改,1 不需要 | 
|     if (this.userInfo && (!this.userInfo.needChangePwd || this.userInfo.needChangePwd == '0')) { | 
|       this.visible.changePwd = true | 
|     } | 
|   }, | 
|   filters: { | 
|     // 展示名称 | 
|     displayName (userInfo) { | 
|       if (userInfo == null) { | 
|         return '' | 
|       } | 
|       if (userInfo.realname != null && userInfo.realname.trim().length > 0) { | 
|         return userInfo.realname | 
|       } | 
|       return userInfo.username | 
|     } | 
|   }, | 
|   methods: { | 
|     ...mapMutations(['setUserInfo', 'switchCollapseMenu', 'clearUserInfo', 'setTopMenuCurrent']), | 
|     // 修改密码 | 
|     changePwd () { | 
|       this.visible.changePwd = true | 
|       this.$nextTick(() => { | 
|         this.$refs.changePwdDataForm.resetFields() | 
|       }) | 
|     }, | 
|     validatePassword (rule, value, callback) { | 
|       if (!value) { | 
|         callback(new Error('请输入密码')) | 
|       } else { | 
|         // const lengthValid = /^.{6,20}$/.test(value) | 
|         // const hasLetter = /[a-zA-Z]/.test(value) | 
|         // const hasNumber = /[0-9]/.test(value) | 
|         // const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(value) | 
|         // | 
|         // const typesCount = [hasLetter, hasNumber, hasSpecial].filter(Boolean).length | 
|         // | 
|         // if (!lengthValid) { | 
|         //   callback(new Error('密码长度需为6到20个字符')) | 
|         // } else if (typesCount < 2) { | 
|         //   callback(new Error('密码需包含字母、数字及特殊字符中的至少两种')) | 
|         // } else { | 
|         //   callback() // 验证通过 | 
|         // } | 
|         let typeCount = 0; | 
|         if (/[a-z]/.test(value)) typeCount++; // 小写字母 | 
|         if (/[A-Z]/.test(value)) typeCount++; // 大写字母 | 
|         if (/\d/.test(value)) typeCount++;    // 数字 | 
|         if (/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(value)) typeCount++; // 特殊字符 | 
|         if (typeCount >= 3) { | 
|           callback() | 
|         } else { | 
|           callback(new Error('至少包括数字、大写字母、小写字母、特殊字符中的三种字符,且至少8位数')) | 
|         } | 
|       } | 
|     }, | 
|     getHeaderNav (item,index) { | 
|       this.currentIndex = index | 
|       if(item.linkType === 0){ | 
|         this.setTopMenuCurrent(item) | 
|       }else{ | 
|         if (item.url && item.url === 'goHKAF' && item.params != null) { | 
|           this.getHKAFHeaderNav(item.params) | 
|         } else if (item.url && item.url.indexOf('http') === 0) { | 
|           window.open(item.url, '_blank') | 
|         } | 
|       } | 
|     }, | 
|     getHKAFHeaderNav (type) { | 
|       getAppHeaderNav(type).then(res => { | 
|         window.open(res, '_blank') | 
|       }) | 
|     }, | 
|     handleTest () { | 
|       const myWindow = window.open('https://10.50.250.253/portal/ui/index?componentId=dfe&componentMenuId=process_apply') | 
|       setTimeout(() => { | 
|         const params = { | 
|           componentId: 'dfe', | 
|           componentMenuId: 'process_apply', | 
|           callback: { | 
|             method: 'dealTlncMsg', | 
|             argument: { | 
|               msgId: '98c256b9-aaff-11ef-8347-fa163ee2c57c', | 
|               moduleId: 'dfeFlowTodoModuleId', | 
|               msgTitle: '请及时处理13856591439发起的请假申请', | 
|               msgStatus: '0', | 
|               msgCreateTime: '今天 15:33', | 
|               msgCreateTimeIso: '2024-11-25T15:33:42.000+08:00', | 
|               serverTime: 1732531014591, | 
|               menuCode: 'process_apply', | 
|               msgStatusStr: '待处理', | 
|               comId: 'dfe', | 
|               userId: '13856591439', | 
|               extendNoShow: '{"processInstanceId":"98a57fe0-aaff-11ef-8347-fa163ee2c57c","processId":"process_dabcfdd39f1b6f46d36a9f4ff6ce1080","param":{"sourceType":"todo","modelCode":"tb_leave_dfe_for_dfe_runtime","processNodeId":"UserTask_dde7d83377343a2d5fa1f60c23b023ef","taskId":"98c256b9-aaff-11ef-8347-fa163ee2c57c"},"process.param.appId":"32ca8770-6f85-11ec-b5a3-991864da52a6","appId":"32ca8770-6f85-11ec-b5a3-991864da52a6","name":"请假申请","taskId":"98c256b9-aaff-11ef-8347-fa163ee2c57c","taskNodeId":"UserTask_dde7d83377343a2d5fa1f60c23b023ef","url":"/dfe-form/process/tlnc/apply"}', | 
|               targetComId: 'dfe', | 
|               moduleName: '流程待办', | 
|               tid: '99cad778-aaff-11ef-9dbf-ff08ba71965c', | 
|               msgEndTime: null, | 
|               msgEndTimeIso: '', | 
|               picUrl: '', | 
|               extendJson: '{"key1":"请及时处理陈鸿飞发起的请假申请"}', | 
|               extendParam: null, | 
|               extendCascade: null, | 
|               createUser: '13856591439', | 
|               webCascadeUrl: null, | 
|               h5CascadeUrl: null, | 
|               cascadeTodoOpenType: null, | 
|               cascadeSourceConfigId: null, | 
|               h5Url: '/h5/pages/form-page/form-page?returnPath=-1&appId=32ca8770-6f85-11ec-b5a3-991864da52a6&taskId=98c256b9-aaff-11ef-8347-fa163ee2c57c&processNodeId=UserTask_dde7d83377343a2d5fa1f60c23b023ef&modelCode=tb_leave_dfe_for_dfe_runtime&type=flowHandle&component=form-apply&_sn=true', | 
|               segmentId: 'dfe-form', | 
|               lastUsers: '陈鸿飞', | 
|               currentUsers: '陈鸿飞', | 
|               todoTypeCode: 'dfe@@tlnc_placeholder_tlnc@@dfeFlowTodoModuleId', | 
|               currentUserIds: '13856591439', | 
|               lastUserIds: '13856591439', | 
|               msgDesc: null, | 
|               widgetUrl: null, | 
|               detailType: null, | 
|               widgetWidth: null, | 
|               widgetHeight: null, | 
|               userIdList: null, | 
|               statusName: null, | 
|               arriveTime: null, | 
|               stayTime: null, | 
|               todoType: null, | 
|               cascadePort: null, | 
|               openMode: null | 
|             } | 
|           }, | 
|           msgType: 'tlnc' | 
|         } | 
|         const argus = JSON.stringify(params) | 
|         myWindow.postMessage('{"method":"goToApp","argument":' + argus + '}', '*') | 
|       }, 8000) | 
|     }, | 
|     // 确定修改密码 | 
|     confirmChangePwd () { | 
|       if (this.isWorking.changePwd) { | 
|         return | 
|       } | 
|       this.$refs.changePwdDataForm.validate((valid) => { | 
|         if (!valid) { | 
|           return | 
|         } | 
|         // 验证两次密码输入是否一致 | 
|         if (this.changePwdData.form.newPwd !== this.changePwdData.form.confirmPwd) { | 
|           this.$tip.warning('两次密码输入不一致') | 
|           return | 
|         } | 
|         // 执行修改 | 
|         this.isWorking.changePwd = true | 
|         updatePwd({ | 
|           oldPwd: this.changePwdData.form.oldPwd, | 
|           newPwd: this.changePwdData.form.newPwd | 
|         }) | 
|           .then(() => { | 
|             this.$tip.apiSuccess('修改成功') | 
|             this.$store.commit('setUserInfo', { needChangePwd: 1 }) | 
|             this.visible.changePwd = false | 
|           }) | 
|           .catch(e => { | 
|             //  this.$tip.apiFailed(e) | 
|           }) | 
|           .finally(() => { | 
|             this.isWorking.changePwd = false | 
|           }) | 
|       }) | 
|     }, | 
|     // 退出登录 | 
|     logout () { | 
|       logout() | 
|         .then(() => { | 
|           this.clearUserInfo() | 
|           // window.location.href = process.env.VUE_APP_CONTEXT_PATH | 
|           // this.$router.push({ name: 'login' }) | 
|           window.location.reload() | 
|         }) | 
|         .catch(e => { | 
|           // this.$tip.apiFailed(e) | 
|         }) | 
|     } | 
|   } | 
| } | 
| </script> | 
|   | 
| <style scoped lang="scss"> | 
| @import "@/assets/style/variables.scss"; | 
|   | 
| .common-header { | 
|   background-color: #2080f7; | 
| } | 
|   | 
| .list { | 
|   flex: 1; | 
|   margin-left: 60px; | 
|   margin-top: 10px; | 
|     display: flex; | 
|     align-items: center; | 
|     .item { | 
|       margin-right: 40px; | 
|       font-size: 16px; | 
|       font-weight: 400; | 
|       display: flex; | 
|       flex-direction: column; | 
|       align-items: center; | 
|       justify-content: flex-start; | 
|       height: 40px; | 
|       cursor: pointer; | 
|   | 
|       .linellae { | 
|         width: 64px; | 
|         height: 2px; | 
|         background: #FFFFFF; | 
|       } | 
|     } | 
|   | 
|     .active { | 
|       font-weight: 500; | 
|     } | 
|   | 
| } | 
|   | 
| .header { | 
|   overflow: hidden; | 
|   // background: #fff; | 
|   height: 100%; | 
|   display: flex; | 
|   justify-content: space-between; | 
|   | 
|   .logo { | 
|     /* background: url("../../assets/images/top_ic_chilun@2x.png") no-repeat; */ | 
|     box-sizing: border-box; | 
|     min-width: 360px; | 
|     height: 56px; | 
|     padding: 10px 30px; | 
|     // flex-shrink: 0; | 
|     line-height: 36px; | 
|     font-size: 22px; | 
|     font-weight: 600; | 
|     color: #fff; | 
|     display: flex; | 
|     align-items: center; | 
|   | 
|     .title { | 
|       font-size: 18px; | 
|       width: 320px; | 
|     } | 
|   | 
|     // display: inline; | 
|     .title-en { | 
|       font-size: 11px; | 
|       font-weight: 500; | 
|       color: rgb(202, 214, 238); | 
|     } | 
|   } | 
|   | 
|   .user { | 
|     width: 152px; | 
|     box-sizing: border-box; | 
|     height: 56px; | 
|     padding-right: 25px; | 
|     background: url("../../assets/images/top_ic_bolang@2x.png") no-repeat; | 
|     flex-shrink: 0; | 
|     text-align: right; | 
|     cursor: pointer; | 
|   | 
|     .el-dropdown { | 
|       top: 2px; | 
|       color: #fff; | 
|     } | 
|   | 
|     img { | 
|       width: 32px; | 
|       position: relative; | 
|       top: 10px; | 
|       margin-right: 10px; | 
|     } | 
|   } | 
| } | 
|   | 
| // 下拉菜单框 | 
| .el-dropdown-menu { | 
|   width: 140px; | 
|   | 
|   .el-dropdown-menu__item:hover { | 
|     background: #e3edfb; | 
|     color: $primary-color; | 
|   } | 
| } | 
| </style> |