Navbar.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <template>
  2. <div class="navbar">
  3. <!-- <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> -->
  4. <!-- <breadcrumb class="breadcrumb-container" /> -->
  5. <div class="left-menu">
  6. <i class='el-icon-location-information topIcon'></i>
  7. <el-popover placement="top-start"
  8. width="200"
  9. trigger="hover"
  10. :content="organName">
  11. <span slot="reference">{{ organName.length > 10 ? organName.substr(0, 10) + '...' : organName}}</span>
  12. </el-popover>
  13. </div>
  14. <div class="right-menu">
  15. <div class="msginfo"
  16. v-permission="'/journals'"
  17. @click="gotoRecode">
  18. <img src='@/assets/images/base/base-bell.svg'/>
  19. <!-- <div class="active"></div> -->
  20. </div>
  21. <el-dropdown class="avatar-container"
  22. trigger="click">
  23. <div class="avatar-wrapper">
  24. <img v-if="$store.getters.avatar"
  25. :src="$store.getters.avatar"
  26. class="user-avatar" />
  27. <img v-else
  28. class="user-avatar"
  29. src="@/assets/images/base/placehorder-icon.png" />
  30. <!-- <i class="el-icon-caret-bottom" /> -->
  31. <span>{{ username }}</span>
  32. </div>
  33. <el-dropdown-menu slot="dropdown"
  34. class="user-dropdown">
  35. <!-- divided -->
  36. <el-dropdown-item>
  37. <span style="display:block;"
  38. @click="resetPassWord">修改密码</span>
  39. </el-dropdown-item>
  40. <el-dropdown-item>
  41. <span style="display:block;"
  42. @click="logout">退出</span>
  43. </el-dropdown-item>
  44. </el-dropdown-menu>
  45. </el-dropdown>
  46. </div>
  47. <el-dialog title="修改密码"
  48. width="500px"
  49. append-to-body
  50. :visible.sync="resetVisible">
  51. <el-form :model="resetForm"
  52. label-position='right'
  53. label-width="100px"
  54. ref='pwdForm'>
  55. <el-form-item label="手机号"
  56. prop="phone">
  57. <div>{{this.$store.getters.phone}}</div>
  58. </el-form-item>
  59. <el-form-item label="新密码"
  60. :rules="[{ required: true, message: '密码不能为空',trigger: 'blur'},{pattern:/^[\w]{6,20}$/,message:'密码为6-20位',trigger: 'blur'}]"
  61. prop="password">
  62. <el-input v-model.trim="resetForm.password"
  63. type='password'
  64. style="width:180px"
  65. autocomplete="off"></el-input>
  66. </el-form-item>
  67. <el-form-item label="再次输入"
  68. :rules="[{ required: true, message: '密码不能为空',trigger: 'blur'},{pattern:/^[\w]{6,20}$/,message:'密码为6-20位',trigger: 'blur'}]"
  69. prop="password2">
  70. <el-input v-model.trim="resetForm.password2"
  71. type='password'
  72. style="width:180px"
  73. autocomplete="off"></el-input>
  74. </el-form-item>
  75. <el-form-item label="验证码"
  76. :rules="[{ required: true, message: '验证码不能为空',trigger: 'blur'}]"
  77. prop="authCode"
  78. style="">
  79. <el-input v-model.trim="resetForm.authCode"
  80. style="width:180px"
  81. autocomplete="off"></el-input>
  82. <el-button :disabled="isDisable"
  83. @click="getCode">{{ btnName }}</el-button>
  84. </el-form-item>
  85. </el-form>
  86. <div slot="footer"
  87. class="dialog-footer">
  88. <el-button @click="resetVisible = false">取 消</el-button>
  89. <el-button type="primary"
  90. @click="submitResetPassWord">确 定</el-button>
  91. </div>
  92. </el-dialog>
  93. </div>
  94. </template>
  95. <script>
  96. import qs from 'qs'
  97. import axios from 'axios'
  98. import { mapGetters } from "vuex";
  99. // import Breadcrumb from '@/components/Breadcrumb'
  100. // import Hamburger from '@/components/Hamburger'
  101. import { resetPassword } from '@/api/buildTeam'
  102. export default {
  103. data () {
  104. return {
  105. username: '',
  106. organName: this.$store.getters.organName,
  107. resetVisible: false,
  108. resetForm: {
  109. phone: '',
  110. authCode: '',
  111. password: '',
  112. password2: ''
  113. },
  114. isDisable: false, // 是否允许发送验证码
  115. timerCount: 60,
  116. btnName: '获取验证码'
  117. }
  118. },
  119. components: {
  120. // Breadcrumb,
  121. // Hamburger
  122. },
  123. computed: {
  124. ...mapGetters(["sidebar", "avatar"])
  125. },
  126. mounted () {
  127. // 手动加入
  128. this.toggleSideBar();
  129. this.username = this.$store.getters.name;
  130. },
  131. methods: {
  132. toggleSideBar () {
  133. this.$store.dispatch("app/toggleSideBar");
  134. },
  135. async logout () {
  136. await this.$store.dispatch("user/logout");
  137. // await this.$store.dispatch("permission/removePermission")
  138. this.$router.push(`/login`);
  139. window.location.reload()
  140. },
  141. gotoRecode () {
  142. this.$router.push('/journal/journal')
  143. },
  144. resetPassWord () {
  145. this.resetVisible = true;
  146. },
  147. submitResetPassWord () {
  148. if (this.resetForm.password !== this.resetForm.password2) {
  149. this.$message.error('两次密码必须相同')
  150. return
  151. }
  152. this.$refs['pwdForm'].validate(res => {
  153. if (res) {
  154. // 发请求
  155. resetPassword({ authCode: this.resetForm.authCode, mobile: this.$store.getters.phone, newPassword: this.resetForm.password }).then(res => {
  156. if (res.code == 200) {
  157. // 修改成功
  158. this.$message.success('修改成功')
  159. this.logout()
  160. }
  161. })
  162. }
  163. })
  164. },
  165. getCode () {
  166. // 获取验证码
  167. if (!this.$store.getters.phone) {
  168. this.$message.error('请输入正确的手机号')
  169. return
  170. }
  171. if (!this.isDisable) {
  172. this.isDisable = true;
  173. // 发请求成功后开启定时器
  174. // 发送验证码
  175. axios.post('/api-web/code/sendSms', qs.stringify({ mobile: this.$store.getters.phone })).then(res => {
  176. if (res.data.code == 200) {
  177. let timer = setInterval(res => {
  178. if (this.timerCount <= 0) {
  179. clearInterval(timer)
  180. this.isDisable = false;
  181. this.btnName = '获取验证码';
  182. this.timerCount = 60;
  183. } else {
  184. this.timerCount--;
  185. this.btnName = `${this.timerCount}s后重试`
  186. }
  187. }, 1000)
  188. }
  189. })
  190. }
  191. }
  192. },
  193. watch: {
  194. resetVisible (val) {
  195. if (!val) {
  196. this.resetForm = {
  197. phone: '',
  198. authCode: '',
  199. password: '',
  200. password2: ''
  201. }
  202. }
  203. }
  204. }
  205. };
  206. </script>
  207. <style lang="scss" scoped>
  208. .navbar {
  209. display: flex;
  210. flex-direction: row;
  211. justify-content: space-between;
  212. height: 60px;
  213. overflow: hidden;
  214. position: relative;
  215. background: #fff;
  216. box-shadow: 0px 8px 20px 0px rgba(0, 0, 0, 0.1);
  217. h2 {
  218. font-size: 18px;
  219. line-height: 60px;
  220. margin: 0 0 0 30px;
  221. display: inline-block;
  222. }
  223. .hamburger-container {
  224. line-height: 60px;
  225. height: 100%;
  226. float: left;
  227. cursor: pointer;
  228. transition: background 0.3s;
  229. -webkit-tap-highlight-color: transparent;
  230. &:hover {
  231. background: rgba(0, 0, 0, 0.025);
  232. }
  233. }
  234. .breadcrumb-container {
  235. float: left;
  236. }
  237. .left-menu {
  238. line-height: 60px;
  239. padding-left: 22px;
  240. font-size: 16px;
  241. color: #444;
  242. .topIcon {
  243. width: 20px;
  244. height: 25px;
  245. }
  246. }
  247. .right-menu {
  248. min-width: 204px;
  249. float: right;
  250. height: 100%;
  251. line-height: 60px;
  252. display: flex;
  253. flex-direction: row;
  254. justify-content: flex-start;
  255. &:focus {
  256. outline: none;
  257. }
  258. .msginfo {
  259. display: flex;
  260. flex-direction: row;
  261. justify-content: flex-start;
  262. align-items: center;
  263. margin-right: 34px;
  264. position: relative;
  265. cursor: pointer;
  266. img {
  267. width: 23px;
  268. height: 30px;
  269. }
  270. .active {
  271. position: absolute;
  272. width: 7px;
  273. height: 7px;
  274. background-color: #f97215;
  275. border-radius: 50%;
  276. top: 20px;
  277. right: -4px;
  278. }
  279. }
  280. .right-menu-item {
  281. display: inline-block;
  282. padding: 0 8px;
  283. height: 100%;
  284. font-size: 14px;
  285. color: #5a5e66;
  286. vertical-align: text-bottom;
  287. &.hover-effect {
  288. cursor: pointer;
  289. transition: background 0.3s;
  290. &:hover {
  291. background: rgba(0, 0, 0, 0.025);
  292. }
  293. }
  294. }
  295. .avatar-container {
  296. height: 60px;
  297. margin-right: 42px;
  298. cursor: pointer;
  299. .avatar-wrapper {
  300. position: relative;
  301. display: flex;
  302. flex-direction: row;
  303. justify-content: flex-start;
  304. align-items: center;
  305. span {
  306. margin-left: 15px;
  307. font-size: 14px;
  308. font-weight: 500;
  309. color: rgba(68, 68, 68, 1);
  310. }
  311. .user-avatar {
  312. cursor: pointer;
  313. width: 32px;
  314. height: 32px;
  315. border: 2px solid #f0f2f5;
  316. border-radius: 50%;
  317. }
  318. .el-icon-caret-bottom {
  319. cursor: pointer;
  320. position: absolute;
  321. right: -20px;
  322. top: 25px;
  323. font-size: 14px;
  324. }
  325. }
  326. }
  327. }
  328. }
  329. </style>