Home.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. <template>
  2. <el-container>
  3. <el-header style="padding: 0">
  4. <el-menu class="el-menu" mode="horizontal">
  5. <el-menu-item index="1" style="width: 200px">
  6. <router-link
  7. to="/home/overview"
  8. style="
  9. display: inline-block;
  10. font-size: 20px;
  11. line-height: 48px;
  12. width: 100%;
  13. text-decoration-line: none;
  14. "
  15. title="回到主页"
  16. >
  17. <img
  18. src="./icon.png"
  19. style="
  20. margin-bottom: 2px;
  21. line-height: 48px;
  22. display: inline-block;
  23. "
  24. />
  25. 云平台主页
  26. </router-link>
  27. </el-menu-item>
  28. <el-menu-item
  29. index="4"
  30. style="float: right"
  31. title="退出系统"
  32. @click="logout"
  33. >
  34. <v-icon name="sign-out-alt" />
  35. <span style="cursor: pointer"> 退出 </span>
  36. </el-menu-item>
  37. <el-menu-item index="3" style="float: right" title="个人信息管理">
  38. <v-icon name="user" />
  39. <span style="cursor: pointer" @click="openUserDialog">
  40. {{ user.displayName }}
  41. </span>
  42. </el-menu-item>
  43. <el-menu-item
  44. index="2"
  45. style="float: right"
  46. title="未读通知"
  47. @click="openMessageHome"
  48. >
  49. <span class="el-icon-message" />
  50. <span style="cursor: pointer">{{ unreadMessageCount }}</span>
  51. </el-menu-item>
  52. <el-menu-item
  53. index="1"
  54. class="navbar-group-item"
  55. style="float: right"
  56. title="机构名称"
  57. >
  58. <v-icon name="users" /> {{ user.rootOrgName }}
  59. </el-menu-item>
  60. </el-menu>
  61. </el-header>
  62. <el-container>
  63. <HomeSide v-if="ifShowHomeSide" :key="sideKey" />
  64. <el-container class="main-body">
  65. <LinkTitles v-if="ifShowHomeSide" :key="Math.random()" />
  66. <router-view class="main-content"></router-view>
  67. <el-footer class="footer">&copy; 启明泰和 2019</el-footer>
  68. </el-container>
  69. </el-container>
  70. <SiteMessagePopup
  71. @changeUnreadMessageCount="changeUnreadMessageCount"
  72. ></SiteMessagePopup>
  73. <!-- 添加用户信息弹出框 -->
  74. <el-dialog
  75. title="个人信息"
  76. width="500px"
  77. :visible.sync="userDialog"
  78. @close="() => $refs.passForm.clearValidate()"
  79. >
  80. <el-tabs value="first">
  81. <el-tab-pane label="用户权限" name="first">
  82. <el-form :inline="true" label-position="right" label-width="90px">
  83. <el-row :gutter="10">
  84. <el-col>
  85. <el-tag
  86. v-for="role in user.roleList"
  87. :key="role.roleId"
  88. type="primary"
  89. style="margin-left: 10px; margin-top: 10px"
  90. >
  91. {{ role.roleName }}
  92. </el-tag>
  93. </el-col>
  94. </el-row>
  95. </el-form>
  96. </el-tab-pane>
  97. <el-tab-pane label="修改密码" name="second">
  98. <el-form
  99. ref="passForm"
  100. :inline="true"
  101. :model="passForm"
  102. :rules="passRules"
  103. label-position="right"
  104. label-width="80px"
  105. >
  106. <el-row>
  107. <el-form-item label="密码" prop="pass">
  108. <el-input
  109. v-model="passForm.pass"
  110. type="password"
  111. style="width: 300px"
  112. auto-complete="off"
  113. placeholder="请输入密码"
  114. />
  115. </el-form-item>
  116. </el-row>
  117. <el-row style="margin-top: 20px">
  118. <el-form-item label="确认密码" prop="checkPass">
  119. <el-input
  120. v-model="passForm.checkPass"
  121. type="password"
  122. style="width: 300px"
  123. auto-complete="off"
  124. placeholder="请输入确认密码"
  125. />
  126. </el-form-item>
  127. </el-row>
  128. <el-row style="margin-top: 20px; margin-left: 100px">
  129. <el-button type="primary" @click="submitForm">保 存</el-button>
  130. <el-button @click="userDialog = false">取 消</el-button>
  131. </el-row>
  132. </el-form>
  133. </el-tab-pane>
  134. </el-tabs>
  135. </el-dialog>
  136. <el-dialog
  137. title="修改密码"
  138. width="500px"
  139. :lock-scroll="true"
  140. :close-on-click-modal="false"
  141. :close-on-press-escape="false"
  142. :show-close="false"
  143. :visible.sync="passWeakDialog"
  144. @close="() => $refs.passWeakForm.clearValidate()"
  145. >
  146. <el-form
  147. ref="passWeakForm"
  148. :inline="true"
  149. :model="passWeakForm"
  150. :rules="passWeakRules"
  151. label-position="right"
  152. label-width="80px"
  153. >
  154. <el-row>
  155. <el-form-item label="密码" prop="pass">
  156. <el-input
  157. v-model="passWeakForm.pass"
  158. type="password"
  159. style="width: 300px"
  160. auto-complete="off"
  161. placeholder="输入新密码"
  162. />
  163. </el-form-item>
  164. </el-row>
  165. <el-row style="margin-top: 20px">
  166. <el-form-item label="确认密码" prop="checkPass">
  167. <el-input
  168. v-model="passWeakForm.checkPass"
  169. type="password"
  170. style="width: 300px"
  171. auto-complete="off"
  172. placeholder="再次输入新密码"
  173. />
  174. </el-form-item>
  175. </el-row>
  176. <el-row style="margin-top: 20px">
  177. <el-form-item
  178. ><span class="passWeakInfo"
  179. >*为保护您的账户安全,请重新录入新密码,以防泄露
  180. </span></el-form-item
  181. >
  182. </el-row>
  183. <el-row style="margin-top: 20px; margin-left: 80px">
  184. <el-button type="primary" @click="submitPassWeakForm"
  185. >确 认</el-button
  186. >
  187. <el-button @click="logout">取 消</el-button>
  188. </el-row>
  189. </el-form>
  190. </el-dialog>
  191. </el-container>
  192. </template>
  193. <script>
  194. import { mapActions, mapState } from "vuex";
  195. import { USER_SIGNOUT, USER_SIGNIN } from "../../store/user";
  196. import { CORE_API } from "@/constants/constants";
  197. import HomeSide from "./HomeSide.vue";
  198. import LinkTitles from "./LinkTitles.vue";
  199. import SiteMessagePopup from "./SiteMessagePopup.vue";
  200. export default {
  201. name: "Home",
  202. components: { HomeSide, LinkTitles, SiteMessagePopup },
  203. data() {
  204. let pswReg =
  205. /^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_]+$)(?![a-z0-9]+$)(?![a-z\W_]+$)(?![0-9\W_]+$)[a-zA-Z0-9\W_]{6,10}$/;
  206. var validatePass = (rule, value, callback) => {
  207. if (value === "") {
  208. callback(new Error("请输入密码"));
  209. } else if (value && !value.match(pswReg)) {
  210. callback(
  211. new Error(
  212. "至少包含大写字母、小写字母、数字、特殊符号中的三种,且长度限制在6-10位!"
  213. )
  214. );
  215. } else {
  216. if (this.passForm.checkPass !== "") {
  217. this.$refs.passForm.validateField("checkPass");
  218. }
  219. callback();
  220. }
  221. };
  222. var validatePass2 = (rule, value, callback) => {
  223. if (value === "") {
  224. callback(new Error("请输入确认密码"));
  225. } else if (value !== this.passForm.pass) {
  226. callback(new Error("两次输入密码不一致!"));
  227. } else {
  228. callback();
  229. }
  230. };
  231. var validatePassWeakPass = (rule, value, callback) => {
  232. if (value === "") {
  233. callback(new Error("请输入密码"));
  234. } else if (value && !value.match(pswReg)) {
  235. callback(
  236. new Error(
  237. "至少包含大写字母、小写字母、数字、特殊符号中的三种,且长度限制在6-10位!"
  238. )
  239. );
  240. } else {
  241. if (this.passWeakForm.checkPass !== "") {
  242. this.$refs.passWeakForm.validateField("checkPass");
  243. }
  244. callback();
  245. }
  246. };
  247. var validatePassWeakPass2 = (rule, value, callback) => {
  248. if (value === "") {
  249. callback(new Error("请输入确认密码"));
  250. } else if (value !== this.passWeakForm.pass) {
  251. callback(new Error("两次输入密码不一致!"));
  252. } else {
  253. callback();
  254. }
  255. };
  256. return {
  257. unreadMessageCount: 0,
  258. userDialog: false,
  259. passWeakDialog: false,
  260. passForm: { pass: "", checkPass: "" },
  261. passWeakForm: { pass: "", checkPass: "" },
  262. passRules: {
  263. pass: [{ validator: validatePass, trigger: "blur" }],
  264. checkPass: [{ validator: validatePass2, trigger: "blur" }],
  265. },
  266. passWeakRules: {
  267. pass: [{ validator: validatePassWeakPass, trigger: "blur" }],
  268. checkPass: [{ validator: validatePassWeakPass2, trigger: "blur" }],
  269. },
  270. };
  271. },
  272. computed: {
  273. ...mapState({ user: (state) => state.user }),
  274. ifShowHomeSide() {
  275. return this.$route.fullPath.startsWith("/home") === false;
  276. },
  277. sideKey() {
  278. const module = this.$route.fullPath.split("/")[1];
  279. return module;
  280. },
  281. },
  282. created() {
  283. if (this.user.passwordWeak) {
  284. this.passWeakDialog = true;
  285. }
  286. },
  287. methods: {
  288. ...mapActions([USER_SIGNOUT, USER_SIGNIN]),
  289. openMessageHome() {
  290. this.$router.push({ path: "/home/site-message" });
  291. },
  292. changeUnreadMessageCount(count) {
  293. this.unreadMessageCount = count;
  294. },
  295. openUserDialog() {
  296. this.passForm = { pass: "", checkPass: "" };
  297. this.userDialog = true;
  298. },
  299. //保存密码
  300. submitForm() {
  301. this.$refs.passForm.validate((valid) => {
  302. if (valid) {
  303. var password = encodeURIComponent(this.passForm.pass);
  304. var url = CORE_API + "/user/password?password=" + password;
  305. this.$httpWithMsg.put(url).then(() => {
  306. this.$notify({
  307. type: "success",
  308. message: "修改密码成功!",
  309. });
  310. this.resetForm();
  311. this.userDialog = false;
  312. });
  313. } else {
  314. console.log("error submit!");
  315. return false;
  316. }
  317. });
  318. },
  319. submitPassWeakForm() {
  320. this.$refs.passWeakForm.validate((valid) => {
  321. if (valid) {
  322. var password = encodeURIComponent(this.passWeakForm.pass);
  323. var url = CORE_API + "/user/password?password=" + password;
  324. this.$httpWithMsg.put(url).then(() => {
  325. this.$notify({
  326. type: "success",
  327. message: "修改密码成功!",
  328. });
  329. this.user.passwordWeak = false;
  330. this.USER_SIGNIN(this.user);
  331. this.$refs.passWeakForm.resetFields();
  332. this.passWeakDialog = false;
  333. });
  334. } else {
  335. console.log("error submit!");
  336. return false;
  337. }
  338. });
  339. },
  340. //重置
  341. resetForm() {
  342. this.$refs.passForm.resetFields();
  343. },
  344. logout() {
  345. const orgId = this.user.rootOrgId;
  346. const getRootOrgId = () => {
  347. if (location.hostname.includes("qmth.com.cn")) {
  348. return "";
  349. } else {
  350. return "?orgId=" + orgId;
  351. }
  352. };
  353. this.$http
  354. .post(CORE_API + "/auth/logout")
  355. .then(() => {
  356. this.USER_SIGNOUT();
  357. window.name = "";
  358. this.$router.replace({
  359. path: "/login" + getRootOrgId(),
  360. });
  361. })
  362. .catch((response) => {
  363. if (response.status == 500) {
  364. this.$notify({
  365. showClose: true,
  366. message: response.data.desc,
  367. type: "error",
  368. });
  369. }
  370. this.USER_SIGNOUT();
  371. window.name = "";
  372. this.$router.replace({
  373. path: "/login" + getRootOrgId(),
  374. });
  375. });
  376. },
  377. },
  378. };
  379. </script>
  380. <style scoped>
  381. .el-menu,
  382. .el-footer {
  383. background-color: #3c8dbd;
  384. color: #ffffff;
  385. text-align: center;
  386. line-height: 60px;
  387. }
  388. .el-footer {
  389. color: #878e93;
  390. background-color: #ecf0f5;
  391. line-height: 40px;
  392. height: 40px !important;
  393. }
  394. .el-menu.el-menu--horizontal {
  395. border-bottom: none;
  396. }
  397. .el-menu >>> .el-menu-item {
  398. color: white !important;
  399. }
  400. .el-menu >>> .el-menu-item:hover,
  401. .el-menu >>> .el-menu-item:focus {
  402. color: white !important;
  403. background-color: rgba(40, 121, 169) !important;
  404. }
  405. .el-menu >>> .is-active.el-menu-item:focus {
  406. color: white !important;
  407. }
  408. .el-menu >>> .navbar-group-item.is-active.el-menu-item:focus {
  409. color: none !important;
  410. }
  411. .el-menu >>> .navbar-group-item.el-menu-item:hover,
  412. .el-menu >>> .navbar-group-item.el-menu-item:focus {
  413. color: white !important;
  414. background-color: transparent !important;
  415. cursor: unset;
  416. border-bottom: none;
  417. }
  418. body > .el-container {
  419. margin-bottom: 40px;
  420. }
  421. .main-body {
  422. min-height: calc(100vh - 100px);
  423. display: flex;
  424. flex-direction: column;
  425. justify-content: space-between;
  426. margin-top: 20px;
  427. margin-left: 20px;
  428. }
  429. .main-content {
  430. min-height: calc(100vh - 60px - 60px - 40px);
  431. margin-top: 20px;
  432. margin-right: 20px;
  433. }
  434. .footer {
  435. justify-self: flex-end;
  436. margin-left: -20px;
  437. }
  438. .passWeakInfo {
  439. color: blue !important;
  440. }
  441. .passWeakErr {
  442. color: red !important;
  443. }
  444. </style>