Navbar.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. <template>
  2. <el-menu
  3. :default-active="activeIndex"
  4. class="el-menu-demo"
  5. mode="horizontal"
  6. background-color=""
  7. text-color="#000"
  8. active-text-color="#4392f7"
  9. @select="handleSelect"
  10. >
  11. <!-- <el-icon
  12. :size="20"
  13. v-show="!menuclose"
  14. class="fold"
  15. @click="SpreadMenu(true)"
  16. ><Fold
  17. /></el-icon>
  18. <el-icon
  19. :size="20"
  20. v-show="menuclose"
  21. class="fold"
  22. @click="SpreadMenu(false)"
  23. ><Expand
  24. /></el-icon> -->
  25. <div class="logo">
  26. <!-- <img src="@/assets/nanchang.png" style="width: 30px; height: 30px" /> -->
  27. <span>智慧公寓管理系统</span>
  28. </div>
  29. <div class="login">
  30. <span class="dateTime">{{ dateTime }}</span>
  31. <!-- <el-badge :value="titlenumber" class="item" v-if="titlenumber">
  32. <img
  33. src="@/assets/news.png"
  34. @click="newsClick"
  35. style="width: 20px; height: 20px; cursor: pointer"
  36. alt=""
  37. />
  38. </el-badge>
  39. <img
  40. v-else
  41. src="@/assets/news.png"
  42. @click="newsClick"
  43. style="width: 20px; height: 20px; cursor: pointer"
  44. alt=""
  45. /> -->
  46. <div class="flex flex-wrap items-center" style="cursor: pointer">
  47. <el-dropdown :hide-on-click="false" trigger="click">
  48. <el-avatar :size="30">
  49. <img
  50. src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
  51. />
  52. </el-avatar>
  53. <template #dropdown>
  54. <el-dropdown-menu>
  55. <el-dropdown-item @click="uppassword">
  56. <el-icon class="switchButton" :size="20" color="#000">
  57. <Lock />
  58. </el-icon>
  59. <span>修改密码</span>
  60. </el-dropdown-item>
  61. <el-dialog
  62. class="updatePass"
  63. custom-class="pw"
  64. v-model="uppasswordShow"
  65. title="修改密码"
  66. width="30%"
  67. :before-close="uppasswordClose"
  68. align-center
  69. :close-on-click-modal="false"
  70. >
  71. <el-form
  72. ref="ruleFormRef"
  73. :model="ruleForm"
  74. :rules="rules"
  75. label-width="100px"
  76. class="demo-ruleForm"
  77. :size="formSize"
  78. label-position="left"
  79. status-icon
  80. >
  81. <el-form-item label="原密码" prop="oldpass">
  82. <el-input
  83. v-model="ruleForm.oldpass"
  84. placeholder="请输入原密码"
  85. clearable
  86. />
  87. </el-form-item>
  88. <el-form-item label="新密码" prop="nowpass">
  89. <el-input
  90. v-model="ruleForm.nowpass"
  91. placeholder="请输入新密码"
  92. clearable
  93. />
  94. </el-form-item>
  95. <el-form-item
  96. label="确定新密码"
  97. prop="correctpass"
  98. style="
  99. padding-bottom: 40px;
  100. border-bottom: 1px solid rgba(230, 230, 230, 1);
  101. "
  102. >
  103. <el-input
  104. v-model="ruleForm.correctpass"
  105. placeholder="请再次输入新密码"
  106. clearable
  107. />
  108. </el-form-item>
  109. <el-form-item class="options">
  110. <el-button
  111. class="queding"
  112. type="primary"
  113. color="rgba(9, 101, 98, 1)"
  114. @click="submitForm(ruleFormRef)"
  115. >
  116. 确定
  117. </el-button>
  118. <el-button class="congzhi" @click="resetForm(ruleFormRef)"
  119. >重置</el-button
  120. >
  121. </el-form-item>
  122. </el-form>
  123. <!-- <template #footer>
  124. <span class="dialog-footer">
  125. <el-button @click="dialogVisible = false">取消</el-button>
  126. <el-button type="primary" @click="dialogVisible = false">
  127. 确定
  128. </el-button>
  129. </span>
  130. </template> -->
  131. </el-dialog>
  132. <el-dropdown-item @click="loginOut">
  133. <el-icon class="switchButton" :size="20" color="#000">
  134. <SwitchButton />
  135. </el-icon>
  136. <span>退出登录</span>
  137. </el-dropdown-item>
  138. </el-dropdown-menu>
  139. </template>
  140. </el-dropdown>
  141. </div>
  142. <span class="name">{{ username }}</span>
  143. </div>
  144. </el-menu>
  145. </template>
  146. <script setup>
  147. import { ref, reactive, onBeforeMount, onMounted, watch } from "vue";
  148. import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
  149. import { useStore } from "vuex";
  150. import { useRouter } from "vue-router";
  151. import { JSEncrypt } from "jsencrypt";
  152. import { dayjs } from "element-plus";
  153. import axios from "axios";
  154. const api = ref();
  155. const store = useStore();
  156. const router = useRouter();
  157. const username = ref(); // 账号名称
  158. const titlenumber = ref(1); // 消息条数
  159. const activeIndex = ref(); // 路由路径
  160. const loginOutDialogVisible = ref(false); // 退出按钮
  161. const menuclose = ref(false); // 左边状态栏展开按钮状态
  162. const uppasswordShow = ref(false); // 修改密码展示框
  163. const ruleForm = reactive({
  164. oldpass: "",
  165. nowpass: "",
  166. correctpass: "",
  167. });
  168. const ruleFormRef = ref();
  169. // 表单验证
  170. const rules = reactive({
  171. oldpass: [
  172. {
  173. required: true,
  174. message: "原密码不能为空",
  175. trigger: "blur",
  176. },
  177. ],
  178. nowpass: [
  179. {
  180. required: true,
  181. message: "确认密码不能为空",
  182. trigger: "blur",
  183. },
  184. {
  185. min: 8,
  186. max: 20,
  187. pattern:
  188. /^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*,\._\+(){}])[0-9a-zA-Z!@#$%^&*,\\._\+(){}]{8,20}$/,
  189. message: "请输入8-20位正确密码(大小写字母·字符·数字)",
  190. trigger: "blur",
  191. },
  192. ],
  193. correctpass: [
  194. {
  195. required: true,
  196. message: "确认密码不能为空",
  197. trigger: "blur",
  198. },
  199. {
  200. min: 8,
  201. max: 20,
  202. pattern:
  203. /^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*,\._\+(){}])[0-9a-zA-Z!@#$%^&*,\\._\+(){}]{8,20}$/,
  204. message: "请输入8-20位正确密码(大小写字母·字符·数字)",
  205. trigger: "blur",
  206. },
  207. ],
  208. // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
  209. });
  210. // 监控消息通知数量
  211. watch(
  212. () => store.state.user.newsNum,
  213. (newValue, oldValue) => {
  214. titlenumber.value = newValue;
  215. console.log(newValue, "监控消息数量");
  216. }
  217. );
  218. // 点击消息通知
  219. const newsClick = () => {
  220. store.commit("indexUp", 0);
  221. sessionStorage.setItem("sidevarItem", 0);
  222. router.push({
  223. path: `/repairs/news`,
  224. });
  225. };
  226. const dateTime = ref(
  227. dayjs().format("YYYY-MM-DD") + ` 星期四 ` + dayjs().format("HH:mm:ss")
  228. ); // 时间
  229. // 选择菜单
  230. const handleSelect = (key, keyPath) => {
  231. store.commit("navbarUpdata", key);
  232. console.log(key);
  233. activeIndex.value = key;
  234. };
  235. // 展开按钮
  236. const SpreadMenu = (flag) => {
  237. store.commit("menuClose", flag);
  238. menuclose.value = flag;
  239. };
  240. // 修改密码
  241. const uppassword = () => {
  242. uppasswordShow.value = true;
  243. };
  244. const uppasswordClose = () => {
  245. uppasswordShow.value = false;
  246. ruleFormRef.value.resetFields();
  247. };
  248. // 提交修改密码表单
  249. const submitForm = async (formEl) => {
  250. if (!formEl) return;
  251. await formEl.validate(async (valid, fields) => {
  252. if (valid) {
  253. let publicKey =
  254. "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMOcPB06u5yKyQsPjfVWiWgbEIrd14kiXNNihciaVKb6HnkQvq7zpQuZ80WEX94spnUMI3iOAl/GmIvHrpGwcbB4hJbznm+PajiwnUSPuCCXA68YJF640cJKb/8KeM7WVz69OFkIEPHhVxOy4FFF5QWe/kt6zOZ19HmE+ak+5x/QIDAQAB";
  255. let encryptor = new JSEncrypt(); // 新建JSEncrypt对象
  256. encryptor.setPublicKey(publicKey); // 设置公钥
  257. let oldPassword = encryptor.encrypt(ruleForm.oldpass); // 对密码进行加密
  258. let newPassword = encryptor.encrypt(ruleForm.nowpass); // 对密码进行加密
  259. let confirmPassword = encryptor.encrypt(ruleForm.correctpass); // 对密码进行加密
  260. let data = {
  261. oldPassword: oldPassword,
  262. newPassword: newPassword,
  263. confirmPassword: confirmPassword,
  264. adminId: sessionStorage.getItem("id"),
  265. };
  266. if (ruleForm.nowpass == ruleForm.correctpass) {
  267. let resUpdata = await axios({
  268. method: "post",
  269. url: api.value + "/login/ChangePassword",
  270. headers: {
  271. // token: sessionStorage.getItem("token"),
  272. // user_head: sessionStorage.getItem("userhead"),
  273. },
  274. data: data,
  275. });
  276. if (resUpdata.data.code == 200) {
  277. ElMessage({
  278. type: "success",
  279. showClose: true,
  280. message: resUpdata.data.message,
  281. center: true,
  282. });
  283. sessionStorage.removeItem("token");
  284. // localStorage.removeItem("pass");
  285. uppasswordShow.value = false;
  286. ruleFormRef.value.resetFields();
  287. ElNotification({
  288. type: "warning",
  289. title: "提示!!!",
  290. message: "密码已修改,请重新登录页面",
  291. // duration: 0,
  292. // position: "top-right",
  293. });
  294. } else {
  295. ElMessage({
  296. type: "error",
  297. showClose: true,
  298. message: res.data.message,
  299. center: true,
  300. });
  301. }
  302. } else {
  303. ElMessage({
  304. type: "error",
  305. showClose: true,
  306. message: "两次密码输入不正确",
  307. center: true,
  308. });
  309. }
  310. } else {
  311. console.log("error submit!", fields);
  312. }
  313. });
  314. };
  315. // 重置表单
  316. const resetForm = (formEl) => {
  317. // console.log("重置表单");
  318. if (!formEl) return;
  319. formEl.resetFields();
  320. };
  321. const loginOut = () => {
  322. ElMessageBox.confirm("是否退出登录?", "提示", {
  323. confirmButtonText: "确认",
  324. cancelButtonText: "取消",
  325. type: "warning",
  326. })
  327. .then(() => {
  328. sessionStorage.removeItem("token");
  329. sessionStorage.removeItem("id");
  330. sessionStorage.removeItem("adminMenuId");
  331. sessionStorage.removeItem("username");
  332. router.push({
  333. path: `/login`,
  334. });
  335. ElMessage({
  336. type: "success",
  337. message: "已退出",
  338. });
  339. })
  340. .catch(() => {
  341. ElMessage({
  342. type: "info",
  343. message: "已取消登录",
  344. });
  345. });
  346. };
  347. onBeforeMount(() => {
  348. api.value = store.state.user.api;
  349. activeIndex.value = store.state.user.navbar;
  350. username.value = sessionStorage.getItem("username");
  351. setInterval(() => {
  352. var week = ["日", "一", "二", "三", "四", "五", "六"];
  353. var datas = dayjs().day();
  354. dateTime.value =
  355. dayjs().format("YYYY-MM-DD") +
  356. ` 星期${week[datas]} ` +
  357. dayjs().format("HH:mm:ss");
  358. }, 1000);
  359. });
  360. </script>
  361. <style scoped lang="scss">
  362. .el-menu--horizontal {
  363. border-bottom: none;
  364. display: flex;
  365. align-items: center;
  366. height: 65px;
  367. // width: 100%;
  368. background-color: #fff;
  369. box-shadow: 5px 5px 10px 0px rgba(213, 228, 252, 1);
  370. .logo {
  371. left: 90px;
  372. display: flex;
  373. align-items: center;
  374. span {
  375. margin-left: 20px;
  376. font-size: 24px;
  377. font-weight: 600;
  378. }
  379. }
  380. .login {
  381. color: #000;
  382. display: flex;
  383. align-items: center;
  384. position: absolute;
  385. right: 10px;
  386. top: 17px;
  387. .dateTime {
  388. margin-right: 20px;
  389. }
  390. .el-badge {
  391. display: flex;
  392. align-items: center;
  393. // :deep(.el-badge__content) {
  394. // width: 2px;
  395. // height: 14px;
  396. // }
  397. }
  398. .items-center {
  399. margin-left: 20px;
  400. }
  401. .name {
  402. height: 20px;
  403. line-height: 20px;
  404. text-decoration: underline;
  405. padding: 0 10px;
  406. margin: 0 10px;
  407. border-left: 2px solid #ccc;
  408. }
  409. .switchButton {
  410. cursor: pointer;
  411. }
  412. }
  413. .login:focus {
  414. outline: none;
  415. }
  416. .fold {
  417. width: 46px;
  418. height: 65px;
  419. }
  420. .fold:hover {
  421. cursor: pointer;
  422. background-color: rgba(67, 146, 249, 0.1);
  423. }
  424. }
  425. :deep(.updatePass) {
  426. // height: 420px;
  427. border-radius: 11px;
  428. .el-dialog__header {
  429. border-radius: 11px 11px 0 0;
  430. background: rgba(237, 241, 245, 1);
  431. font-weight: 600;
  432. margin: 0;
  433. .el-dialog__headerbtn {
  434. outline: none;
  435. }
  436. }
  437. .el-dialog__body {
  438. padding: 20px 30px 20px 30px;
  439. .table {
  440. width: 100%;
  441. border-radius: 4px;
  442. overflow: auto;
  443. display: flex;
  444. &::-webkit-scrollbar-track {
  445. background-color: #daeeff;
  446. border-radius: 4px;
  447. }
  448. // 滚动条的滚动区域(轨道)
  449. &::-webkit-scrollbar {
  450. background-color: #242424;
  451. height: 5px;
  452. width: 4px;
  453. border-radius: 4px;
  454. }
  455. // 滚动条的可拖拽部分(滑块)
  456. &::-webkit-scrollbar-thumb {
  457. background: #57b2ff;
  458. border-radius: 4px;
  459. }
  460. .items {
  461. &:last-child {
  462. border-right: 1px solid rgba(230, 230, 230, 1);
  463. }
  464. .txt {
  465. height: 40px;
  466. line-height: 40px;
  467. text-align: center;
  468. border-left: 1px solid rgba(230, 230, 230, 1);
  469. border-top: 1px solid rgba(230, 230, 230, 1);
  470. &.scoreItem {
  471. background-color: rgba(240, 243, 247, 1);
  472. }
  473. &:nth-child(2) {
  474. border-bottom: 1px solid rgba(230, 230, 230, 1);
  475. }
  476. .el-input__wrapper {
  477. box-shadow: none;
  478. .el-input__inner {
  479. text-align: center;
  480. }
  481. }
  482. }
  483. .items_li {
  484. display: flex;
  485. flex-wrap: nowrap;
  486. .lis {
  487. width: 120px;
  488. }
  489. }
  490. }
  491. }
  492. .options {
  493. margin: 20px 30px 0 0;
  494. width: 100%;
  495. display: flex;
  496. flex-direction: row-reverse;
  497. .queding {
  498. color: #fff;
  499. margin-left: 15px;
  500. }
  501. }
  502. }
  503. }
  504. .el-dialog__body {
  505. .options {
  506. display: flex;
  507. flex-direction: row-reverse;
  508. :deep(.el-form-item__content) {
  509. margin-left: 0 !important;
  510. flex: none;
  511. }
  512. :deep(.queding) {
  513. background-color: rgba(41, 109, 227, 1) !important;
  514. border: 0.5px solid rgba(41, 109, 227, 1) !important;
  515. }
  516. }
  517. }
  518. </style>
  519. <style lang="scss">
  520. .el-overlay {
  521. .el-message-box__btns {
  522. .el-button--primary {
  523. background-color: rgba(41, 109, 227, 1) !important;
  524. border: 0.5px solid rgba(41, 109, 227, 1) !important;
  525. }
  526. }
  527. .el-overlay-dialog {
  528. .pw {
  529. border-radius: 11px;
  530. .el-dialog__header {
  531. border-radius: 11px 11px 0 0;
  532. background: rgba(237, 241, 245, 1);
  533. font-weight: 600;
  534. margin: 0;
  535. .el-dialog__headerbtn {
  536. outline: none;
  537. }
  538. }
  539. .el-dialog__body {
  540. padding: 30px 20px 10px 20px;
  541. .el-input {
  542. width: 200px;
  543. }
  544. .options {
  545. margin-left: 170px;
  546. }
  547. }
  548. }
  549. }
  550. }
  551. </style>