|
@@ -0,0 +1,369 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="wrapper">
|
|
|
|
+ <header class="main-header">
|
|
|
|
+ <!-- Logo -->
|
|
|
|
+ <a href="javascript:void(0)" class="logo">
|
|
|
|
+ <span class="logo-mini"><b>云</b></span>
|
|
|
|
+ <span class="logo-lg"><b>云平台</b></span>
|
|
|
|
+ </a>
|
|
|
|
+
|
|
|
|
+ <!-- Header Navbar: style can be found in header.less -->
|
|
|
|
+ <nav class="navbar navbar-static-top">
|
|
|
|
+ <!-- Navbar Right Menu -->
|
|
|
|
+ <div class="navbar-custom-menu">
|
|
|
|
+ <ul class="nav navbar-nav">
|
|
|
|
+
|
|
|
|
+ <li class="user user-menu">
|
|
|
|
+ <a href="javascript:void(0)">
|
|
|
|
+ <i class="fa fa-home"></i>
|
|
|
|
+ <span>{{user.rootOrgName}}</span>
|
|
|
|
+ </a>
|
|
|
|
+ </li>
|
|
|
|
+
|
|
|
|
+ <li class="dropdown user user-menu">
|
|
|
|
+ <a href="javascript:void(0)" @click="openUserDialog" class="dropdown-toggle" data-toggle="dropdown">
|
|
|
|
+ <span class="hidden-xs">
|
|
|
|
+ <i class="fa fa-user"></i>
|
|
|
|
+ {{user.displayName}}
|
|
|
|
+ </span>
|
|
|
|
+ </a>
|
|
|
|
+ </li>
|
|
|
|
+
|
|
|
|
+ <li class="user user-menu">
|
|
|
|
+ <a href="javascript:void(0)" @click="logout">
|
|
|
|
+ <i class="fa fa-sign-out"></i>
|
|
|
|
+ <span>退出</span>
|
|
|
|
+ </a>
|
|
|
|
+ </li>
|
|
|
|
+
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ </nav>
|
|
|
|
+ </header>
|
|
|
|
+
|
|
|
|
+ <div class="main-content">
|
|
|
|
+ <section class="content">
|
|
|
|
+ <div class="row">
|
|
|
|
+ <ul class="center">
|
|
|
|
+
|
|
|
|
+ <li class="menu" v-for="menu in menuList" v-if="menu.parentId == null" :key="menu.id" @click="toApp(menu.ext1)">
|
|
|
|
+ <svg class="icon" aria-hidden="true">
|
|
|
|
+ <use v-if="menu.code == 'BASIC'" xlink:href="#icon-core"></use>
|
|
|
|
+ <use v-if="menu.code == 'EXAM_WORK'" xlink:href="#icon-exam-work"></use>
|
|
|
|
+ <use v-if="menu.code == 'QUESTIONS'" xlink:href="#icon-question"></use>
|
|
|
|
+ <use v-if="menu.code == 'ONLINE_EXAM'" xlink:href="#icon-oe"></use>
|
|
|
|
+ <use v-if="menu.code == 'marking_admin'" xlink:href="#icon-marking"></use>
|
|
|
|
+ <use v-if="menu.code == 'PRINT'" xlink:href="#icon-print"></use>
|
|
|
|
+ <use v-if="menu.code == 'REPORTS'" xlink:href="#icon-stat"></use>
|
|
|
|
+ </svg>
|
|
|
|
+ <div>{{menu.name}}</div>
|
|
|
|
+ </li>
|
|
|
|
+
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ </section>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 添加用户信息弹出框 -->
|
|
|
|
+ <el-dialog title="个人信息" v-model="userDialog">
|
|
|
|
+ <el-tabs v-model="activeName">
|
|
|
|
+ <el-tab-pane label="用户权限" name="first">
|
|
|
|
+ <el-form :inline="true" label-position="right" label-width="90px">
|
|
|
|
+ <el-row :gutter="10">
|
|
|
|
+ <el-col>
|
|
|
|
+ <el-tag v-for="role in user.roleList" :key="role.roleId" type="primary" style="margin-left:10px;margin-top:10px;">
|
|
|
|
+ {{role.roleName}}
|
|
|
|
+ </el-tag>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ </el-form>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ <el-tab-pane label="修改密码" name="second">
|
|
|
|
+ <el-form :inline="true" :model="passForm" ref="passForm" :rules="passRules" label-position="right" label-width="90px">
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-form-item label="密码" label-width="120px" prop="pass">
|
|
|
|
+ <el-input type="password" class="pull_length" v-model="passForm.pass" auto-complete="off" placeholder="请输入密码"></el-input>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-form-item label="确认密码" label-width="120px" prop="checkPass">
|
|
|
|
+ <el-input type="password" class="pull_length" v-model="passForm.checkPass" auto-complete="off" placeholder="请输入确认密码"></el-input>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row style="margin-left:100px">
|
|
|
|
+ <el-button type="primary" @click="submitForm">保 存</el-button>
|
|
|
|
+ <el-button @click="userDialog = false">取 消</el-button>
|
|
|
|
+ </el-row>
|
|
|
|
+ </el-form>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ </el-tabs>
|
|
|
|
+ </el-dialog>
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import { mapActions, mapState } from "vuex";
|
|
|
|
+import { USER_SIGNOUT } from "../store/user";
|
|
|
|
+import { core_api } from "../constants/constants";
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ data() {
|
|
|
|
+ var validatePass = (rule, value, callback) => {
|
|
|
|
+ if (value === "") {
|
|
|
|
+ callback(new Error("请输入密码"));
|
|
|
|
+ } else {
|
|
|
|
+ if (this.passForm.checkPass !== "") {
|
|
|
|
+ this.$refs.passForm.validateField("checkPass");
|
|
|
|
+ }
|
|
|
|
+ callback();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ var validatePass2 = (rule, value, callback) => {
|
|
|
|
+ if (value === "") {
|
|
|
|
+ callback(new Error("请输入确认密码"));
|
|
|
|
+ } else if (value !== this.passForm.pass) {
|
|
|
|
+ callback(new Error("两次输入密码不一致!"));
|
|
|
|
+ } else {
|
|
|
|
+ callback();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ return {
|
|
|
|
+ authParams: "",
|
|
|
|
+ activeName: "first",
|
|
|
|
+ menuList: [],
|
|
|
|
+ userDialog: false,
|
|
|
|
+ passForm: { pass: "", checkPass: "" },
|
|
|
|
+ passRules: {
|
|
|
|
+ pass: [{ validator: validatePass, trigger: "blur" }],
|
|
|
|
+ checkPass: [{ validator: validatePass2, trigger: "blur" }]
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ components: {},
|
|
|
|
+ computed: {
|
|
|
|
+ ...mapState({ user: state => state.user })
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ ...mapActions([USER_SIGNOUT]),
|
|
|
|
+ openUserDialog() {
|
|
|
|
+ this.passForm = { pass: "", checkPass: "" };
|
|
|
|
+ this.userDialog = true;
|
|
|
|
+ },
|
|
|
|
+ //保存密码
|
|
|
|
+ submitForm() {
|
|
|
|
+ this.$refs.passForm.validate(valid => {
|
|
|
|
+ if (valid) {
|
|
|
|
+ var userId = this.user.userId;
|
|
|
|
+ var password = encodeURIComponent(this.passForm.pass);
|
|
|
|
+ var url =
|
|
|
|
+ core_api +
|
|
|
|
+ "/user/password?userId=" +
|
|
|
|
+ userId +
|
|
|
|
+ "&password=" +
|
|
|
|
+ password;
|
|
|
|
+ this.$http.put(url).then(response => {
|
|
|
|
+ this.$notify({
|
|
|
|
+ type: "success",
|
|
|
|
+ message: "修改密码成功!"
|
|
|
|
+ });
|
|
|
|
+ this.resetForm();
|
|
|
|
+ this.userDialog = false;
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ console.log("error submit!");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ //重置
|
|
|
|
+ resetForm() {
|
|
|
|
+ this.$refs.passForm.resetFields();
|
|
|
|
+ },
|
|
|
|
+ isSuperAdmin() {
|
|
|
|
+ if (!this.user.roleList) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ for (let role of this.user.roleList) {
|
|
|
|
+ if (role.roleCode == "SUPER_ADMIN") {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+ checkAccess(app) {
|
|
|
|
+ if (this.isSuperAdmin()) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ for (let role of this.user.roleList) {
|
|
|
|
+ if (this.user.roleList.length == 1 && role.roleCode == "STUDENT") {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ logout() {
|
|
|
|
+ this.$http
|
|
|
|
+ .post(core_api + "/auth/logout")
|
|
|
|
+ .then(response => {
|
|
|
|
+ const orgId = this.user.rootOrgId;
|
|
|
|
+ this.USER_SIGNOUT();
|
|
|
|
+ window.name = "";
|
|
|
|
+ this.$router.replace({
|
|
|
|
+ path: "/login" + "?orgId=" + orgId
|
|
|
|
+ });
|
|
|
|
+ })
|
|
|
|
+ .catch(response => {
|
|
|
|
+ const orgId = this.user.rootOrgId;
|
|
|
|
+ if (response.status == 500) {
|
|
|
|
+ this.$notify({
|
|
|
|
+ showClose: true,
|
|
|
|
+ message: response.data.desc,
|
|
|
|
+ type: "error"
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ this.USER_SIGNOUT();
|
|
|
|
+ window.name = "";
|
|
|
|
+ this.$router.replace({
|
|
|
|
+ path: "/login" + "?orgId=" + orgId
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ checkLogin: function() {
|
|
|
|
+ var url = core_api + "/auth/getLoginUser";
|
|
|
|
+ const params = new URLSearchParams();
|
|
|
|
+ params.append("key", this.user.key);
|
|
|
|
+ params.append("token", this.user.token);
|
|
|
|
+ this.$http
|
|
|
|
+ .post(url, params, {
|
|
|
|
+ headers: { "content-type": "application/x-www-form-urlencoded" }
|
|
|
|
+ })
|
|
|
|
+ .then(response => {
|
|
|
|
+ console.log(response);
|
|
|
|
+ })
|
|
|
|
+ .catch(response => {
|
|
|
|
+ if (response.status == 500) {
|
|
|
|
+ this.$notify({
|
|
|
|
+ showClose: true,
|
|
|
|
+ message: response.data.desc,
|
|
|
|
+ type: "error"
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ this.logout();
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ toApp(port) {
|
|
|
|
+ this.$http.get(core_api).then(response => {
|
|
|
|
+ window.location.href =
|
|
|
|
+ "http://" +
|
|
|
|
+ window.location.hostname +
|
|
|
|
+ ":" +
|
|
|
|
+ port +
|
|
|
|
+ "/#/access?" +
|
|
|
|
+ this.authParams;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ created() {
|
|
|
|
+ console.log("user:", this.user);
|
|
|
|
+ this.checkLogin();
|
|
|
|
+ this.authParams =
|
|
|
|
+ "key=" +
|
|
|
|
+ this.user.key +
|
|
|
|
+ "&token=" +
|
|
|
|
+ this.user.token +
|
|
|
|
+ "&indexUrl=" +
|
|
|
|
+ encodeURIComponent("http://" + window.location.host + "/#/index") +
|
|
|
|
+ "&loginUrl=" +
|
|
|
|
+ encodeURIComponent("http://" + window.location.host + "/#/login");
|
|
|
|
+
|
|
|
|
+ var url = core_api + "/rolePrivilege/getUserPrivileges";
|
|
|
|
+ const params = new URLSearchParams();
|
|
|
|
+ params.append("groupCode", "PORTAL_MENUS");
|
|
|
|
+ params.append("full", false);
|
|
|
|
+ this.$http
|
|
|
|
+ .post(url, params, {
|
|
|
|
+ headers: { "content-type": "application/x-www-form-urlencoded" }
|
|
|
|
+ })
|
|
|
|
+ .then(response => {
|
|
|
|
+ this.menuList = response.data;
|
|
|
|
+ })
|
|
|
|
+ .catch(response => {
|
|
|
|
+ if (response.status == 500) {
|
|
|
|
+ this.$notify({
|
|
|
|
+ showClose: true,
|
|
|
|
+ message: response.data.desc,
|
|
|
|
+ type: "error"
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="css">
|
|
|
|
+.icon {
|
|
|
|
+ /* 通过设置 font-size 来改变图标大小 */
|
|
|
|
+ width: 5em;
|
|
|
|
+ height: 5em;
|
|
|
|
+ /* 图标和文字相邻时,垂直对齐 */
|
|
|
|
+ vertical-align: -0.15em;
|
|
|
|
+ /* 通过设置 color 来改变 SVG 的颜色/fill */
|
|
|
|
+ fill: currentColor;
|
|
|
|
+ /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
|
|
|
+ normalize.css 中也包含这行 */
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ margin-top: 10px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+span.logo-lg {
|
|
|
|
+ font-family: "Micrsoft YaHei";
|
|
|
|
+ font-size: 30px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.main-content {
|
|
|
|
+ background-color: #ecf0f5;
|
|
|
|
+ width: 100%;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.center {
|
|
|
|
+ margin: 0 auto 0 auto;
|
|
|
|
+ margin-top: 10%;
|
|
|
|
+ margin-left: 20%;
|
|
|
|
+ text-align: center;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.menu {
|
|
|
|
+ font-family: "Micrsoft YaHei";
|
|
|
|
+ color: #3c8dbc;
|
|
|
|
+ width: 200px;
|
|
|
|
+ height: 120px;
|
|
|
|
+ margin-right: 50px;
|
|
|
|
+ margin-bottom: 50px;
|
|
|
|
+ float: left;
|
|
|
|
+ border-style: solid;
|
|
|
|
+ border-width: 5px;
|
|
|
|
+ border-color: #3c8dbc;
|
|
|
|
+ border-radius: 25px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.menu:hover {
|
|
|
|
+ border-width: 5px;
|
|
|
|
+ box-shadow: 0 0 50px;
|
|
|
|
+ animation: menu-jump 500ms infinite;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+@keyframes menu-jump {
|
|
|
|
+ 0% {
|
|
|
|
+ transform: translate(0px, 0px);
|
|
|
|
+ }
|
|
|
|
+ 50% {
|
|
|
|
+ transform: translate(0px, -10px);
|
|
|
|
+ }
|
|
|
|
+ 100% {
|
|
|
|
+ transform: translate(0px, 0px);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|