Bladeren bron

登录页

dusenyao 1 jaar geleden
bovenliggende
commit
2713e058b5

+ 11 - 3
main.js

@@ -2,11 +2,14 @@ const { app, BrowserWindow } = require('electron');
 const path = require('path');
 const url = require('url');
 
+let win = null;
+
 // 创建窗口
 const createWindow = () => {
-  const win = new BrowserWindow({
-    width: 1200,
-    height: 800,
+  win = new BrowserWindow({
+    // width: 1200,
+    // height: 800,
+    show: false, // 是否显示窗口
     autoHideMenuBar: true, // 隐藏菜单栏
     webPreferences: {
       nodeIntegration: true, // 是否集成 Node.js
@@ -23,6 +26,11 @@ const createWindow = () => {
       hash: '/login',
     }),
   );
+
+  win.once('ready-to-show', () => {
+    win.maximize();
+    win.show();
+  });
 };
 
 // 当 Electron 完成初始化并准备创建浏览器窗口时调用此方法

+ 10 - 7
public/index.html

@@ -1,15 +1,18 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="">
   <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
-    <title><%= htmlWebpackPlugin.options.title %></title>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
+    <title><%= webpackConfig.name %></title>
   </head>
   <body>
     <noscript>
-      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+      <strong
+        >We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to
+        continue.</strong
+      >
     </noscript>
     <div id="app"></div>
     <!-- built files will be auto injected -->

BIN
src/assets/login/login-bg.png


BIN
src/assets/logo.png


+ 5 - 0
src/icons/svg/practice.svg

@@ -0,0 +1,5 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <path
+    d="M12.6666 14.6666H3.33331C2.22875 14.6666 1.33331 13.7712 1.33331 12.6666V1.99992C1.33331 1.63173 1.63179 1.33325 1.99998 1.33325H11.3333C11.7015 1.33325 12 1.63173 12 1.99992V9.99992H14.6666V12.6666C14.6666 13.7712 13.7712 14.6666 12.6666 14.6666ZM12 11.3333V12.6666C12 13.0348 12.2984 13.3333 12.6666 13.3333C13.0348 13.3333 13.3333 13.0348 13.3333 12.6666V11.3333H12ZM10.6666 13.3333V2.66659H2.66665V12.6666C2.66665 13.0348 2.96513 13.3333 3.33331 13.3333H10.6666ZM3.99998 4.66659H9.33331V5.99992H3.99998V4.66659ZM3.99998 7.33325H9.33331V8.66659H3.99998V7.33325ZM3.99998 9.99992H7.33331V11.3333H3.99998V9.99992Z"
+    fill="currentColor" />
+</svg>

+ 0 - 23
src/layouts/default/header/index.vue

@@ -2,17 +2,6 @@
   <header class="header">
     <el-image class="logo" :src="$store.state.app.config.logo_image_url" />
 
-    <!-- <ul class="header-list">
-      <li
-        v-for="({ name }, i) in projectList"
-        :key="i"
-        :class="i === LoginNavIndex ? 'active' : ''"
-        @click="handleCommand(i)"
-      >
-        {{ name }}
-      </li>
-    </ul> -->
-
     <div v-if="!token" class="selectLoginOrRegistration">
       <span>登录</span>
     </div>
@@ -64,20 +53,8 @@ export default {
     });
   },
   methods: {
-    // 切换项目
-    handleCommand(command) {
-      this.LoginNavIndex = command;
-      if (!this.token) {
-        this.$message.warning('请先登录');
-        window.location.href = '/';
-        return;
-      }
-      const relative_path = this.projectList[command].relative_path;
-      location.href = relative_path;
-    },
     logout() {
       this.$store.dispatch('user/signOut');
-      // window.location.href = '/';
       this.$router.push('/login');
     },
   },

+ 1 - 1
src/main.js

@@ -9,7 +9,7 @@ import '@/styles/index.scss';
 import '@/utils/filter';
 
 import ElementUI from 'element-ui';
-import 'element-ui/lib/theme-chalk/index.css';
+import '@/styles/element-variables.scss';
 
 import { setupRouterGuard } from '@/router/guard';
 

+ 4 - 4
src/router/guard/index.js

@@ -1,17 +1,17 @@
 import { getSessionID, getConfig } from '@/utils/auth';
+import store from '@/store';
 
 import NProgress from 'nprogress';
 import 'nprogress/nprogress.css';
 NProgress.configure({ showSpinner: false });
 
-const whiteList = ['/login', '/EnterSys', '/open/share/exercise']; // 重定向白名单
+const whiteList = ['/login']; // 重定向白名单
 
 export function setupRouterGuard(router) {
   // 全局前置守卫
   router.beforeEach(async (to, from, next) => {
     NProgress.start();
-
-    if (getSessionID() && getConfig()) {
+    if (store.state.user?.access_token) {
       if (to.path === '/login') {
         next({ path: '/' });
         NProgress.done();
@@ -24,7 +24,7 @@ export function setupRouterGuard(router) {
     } else {
       // 其他无权访问的页面将重定向到登录页面
       if (process.env.NODE_ENV === 'production') {
-        window.location.href = '/';
+        next('/login');
       } else {
         next('/login');
       }

+ 5 - 1
src/router/modules/basic.js

@@ -10,11 +10,15 @@ export const homePage = {
   path: '/',
   component: DEFAULT,
   redirect: '/home',
+  meta: {
+    title: '教材管理',
+    icon: 'practice',
+  },
   children: [
     {
       path: '/home',
       name: 'Home',
-      component: () => import('@/views/userInfo.vue'),
+      component: () => import('@/views/home/index.vue'),
     },
   ],
 };

+ 5 - 5
src/store/modules/user.js

@@ -22,7 +22,7 @@ const getDefaultSate = () => {
 const state = getDefaultSate();
 
 const mutations = {
-  [user.RESET_STATE]: state => {
+  [user.RESET_STATE]: (state) => {
     Object.assign(state, getDefaultSate());
   },
   [user.SET_USER_INFO]: (
@@ -46,12 +46,12 @@ const actions = {
   login({ commit }, loginForm) {
     return new Promise((reslove, reject) => {
       login(loginForm)
-        .then(response => {
+        .then((response) => {
           setToken(response);
           commit(user.SET_USER_INFO, response);
           reslove();
         })
-        .catch(error => {
+        .catch((error) => {
           reject(error);
         });
     });
@@ -59,7 +59,7 @@ const actions = {
 
   // 用户退出
   signOut({ commit }) {
-    return new Promise(resolve => {
+    return new Promise((resolve) => {
       removeToken();
       resetRouter();
       commit(user.RESET_STATE);
@@ -68,7 +68,7 @@ const actions = {
   },
 
   enterSys({ commit }) {
-    return new Promise(reslove => {
+    return new Promise((reslove) => {
       commit(user.RESET_STATE);
       reslove();
     });

+ 26 - 0
src/styles/element-variables.scss

@@ -0,0 +1,26 @@
+@use './variables.scss' as *;
+
+// base
+$--color-primary: $main-color;
+
+// table
+$--table-header-background-color: $fill-color;
+$--table-border: 1px solid $border-color;
+$--table-header-font-color: $font-color;
+
+// input
+$--input-background-color: $fill-color;
+$--input-border: 1px solid $fill-color;
+$--input-small-font-size: 14px;
+
+// button
+$--button-small-font-size: 14px;
+$--button-primary-background-color: $main-color;
+$--button-default-background-color: #f3f3f3;
+$--button-default-border-color: #f3f3f3;
+$--button-small-padding-vertical: 8px;
+
+/* 改变 icon 字体路径变量,必需 */
+$--font-path: '~element-ui/lib/theme-chalk/fonts';
+
+@import '~element-ui/packages/theme-chalk/src/index';

+ 16 - 0
src/styles/element.scss

@@ -0,0 +1,16 @@
+@use './variables.scss' as *;
+
+div.el-table {
+  .el-table__cell {
+    padding: 8px 0;
+  }
+
+  &--small {
+    font-size: 14px;
+    color: $font-color;
+  }
+}
+
+.el-pagination {
+  text-align: right;
+}

+ 3 - 0
src/styles/index.scss

@@ -1,3 +1,6 @@
+@use './variables.scss' as *;
+@use './element.scss' as *;
+
 :root {
   box-sizing: border-box;
   font-family: 'Inter', system-ui, 'Avenir', 'Helvetica', 'Arial', sans-serif;

+ 5 - 17
src/utils/http.js

@@ -2,7 +2,6 @@ import axios from 'axios';
 // import store from '@/store';
 
 import { Message } from 'element-ui';
-import { getToken } from '@/utils/auth';
 import store from '@/store';
 
 const service = axios.create({
@@ -12,18 +11,18 @@ const service = axios.create({
 
 // 请求拦截器
 service.interceptors.request.use(
-  config => {
+  (config) => {
     config.headers['Content-Type'] = 'application/json';
     return config;
   },
-  error => {
+  (error) => {
     return Promise.reject(error);
   },
 );
 
 // 响应拦截器
 service.interceptors.response.use(
-  response => {
+  (response) => {
     const res = response.data;
     const { code, status, message, error } = res;
     if (code === 404) {
@@ -54,24 +53,13 @@ service.interceptors.response.use(
         type: 'error',
         duration: 3 * 1000,
       });
-      // store.dispatch('user/signOut');
-      const match = /#\/(.*?)\?/.exec(window.location.hash); // 使用 exec 方法进行匹配
 
-      // 答题跳转链接
-      let extractedString = '';
-      if (match && match.length > 1) {
-        extractedString = match[1];
-      }
-      // 答题链接特殊处理
-      if (extractedString === 'open/share/exercise') {
-        return Promise.reject(new Error(`${error}` || 'Error'));
-      }
-      // window.location.href = '/';
+      return Promise.reject(new Error(`${error}` || 'Error'));
     }
 
     return res;
   },
-  error => {
+  (error) => {
     if (error.code === 'ERR_CANCELED') {
       return Message.success('取消上传成功');
     }

+ 43 - 4
src/views/home/index.vue

@@ -1,15 +1,54 @@
 <template>
-  <div></div>
+  <div class="home">
+    <div></div>
+    <div></div>
+    <div></div>
+    <el-table :data="data" height="100%">
+      <el-table-column prop="name" label="教材名称" width="180" />
+    </el-table>
+    <el-pagination
+      background
+      :current-page="cur_page"
+      :page-sizes="[10, 20, 30, 40, 50]"
+      :page-size="page_capacity"
+      layout="total, prev, pager, next, sizes, jumper"
+      :total="total"
+      @prev-click="changePage"
+      @next-click="changePage"
+      @current-change="changePage"
+      @size-change="changePageSize"
+    />
+  </div>
 </template>
 
 <script>
 export default {
   name: 'HomePage',
   data() {
-    return {};
+    return {
+      data: undefined,
+      cur_page: 1,
+      page_capacity: 10,
+      total: 0,
+    };
+  },
+  methods: {
+    changePage(number) {
+      this.cur_page = number;
+    },
+    changePageSize(size) {
+      this.page_capacity = size;
+    },
   },
-  methods: {},
 };
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.home {
+  min-height: calc(100% - 16px);
+  padding: 24px;
+  margin: 0 24px 16px;
+  background-color: #fff;
+  border-radius: 4px;
+}
+</style>

+ 42 - 10
src/views/login/index.vue

@@ -1,16 +1,16 @@
 <template>
   <div class="login">
     <main class="login-container">
-      <h1 class="title">用户登录</h1>
+      <div class="title">登录</div>
       <el-form ref="loginForm" :model="form" :rules="rules" label-position="right">
-        <el-form-item prop="user_name">
+        <el-form-item prop="user_name" label="用户名">
           <el-input v-model="form.user_name" />
         </el-form-item>
-        <el-form-item prop="password">
+        <el-form-item prop="password" label="密码">
           <el-input v-model="form.password" type="password" show-password />
         </el-form-item>
-        <el-form-item prop="verification_code_image_text" class="verification-code">
-          <el-input v-model="form.verification_code_image_text" placeholder="验证码" @keyup.enter.native="signIn" />
+        <el-form-item prop="verification_code_image_text" class="verification-code" label="验证码">
+          <el-input v-model="form.verification_code_image_text" @keyup.enter.native="signIn" />
           <el-image
             v-if="image_content_base64.length > 0"
             :src="`data:image/jpg;base64,${image_content_base64}`"
@@ -104,29 +104,61 @@ export default {
   width: 100%;
   height: 100%;
   overflow: hidden;
-  background-color: #2d3a4b;
+  background: #2148c0 url('~@/assets/login/login-bg.png') no-repeat center center / cover;
 
   &-container {
     padding: 200px;
 
     .title {
-      margin-bottom: 20px;
-      color: #abc;
+      margin-bottom: 28px;
+      font-size: 24px;
+      color: #fff;
       text-align: center;
     }
 
     :deep .el-form {
       max-width: 400px;
+      padding: 24px 32px;
       margin: 0 auto;
+      background-color: #fff;
+      border-radius: 16px;
+
+      &-item {
+        &__label {
+          margin-bottom: 8px;
+          font-size: 18px;
+          font-weight: bold;
+          color: #000;
+
+          &::before {
+            display: none;
+          }
+        }
+      }
+
+      .el-input {
+        &__inner {
+          height: 40px;
+          line-height: 40px;
+          background-color: #fff;
+        }
+      }
 
       .verification-code {
+        display: flex;
+        flex-direction: column;
+
+        label {
+          text-align: left;
+        }
+
         .el-input {
-          width: calc(100% - 90px);
+          width: calc(100% - 112px);
           margin-right: 10px;
         }
 
         .el-image {
-          height: 30px;
+          height: 38px;
           vertical-align: bottom;
           cursor: pointer;
         }

+ 0 - 32
src/views/userInfo.vue

@@ -1,32 +0,0 @@
-<template>
-  <div class="user-info"></div>
-</template>
-
-<script>
-import { GetMyUserInfo } from '@/api/user';
-
-export default {
-  name: 'UserInfo',
-  data() {
-    return {
-      userInfo: {},
-    };
-  },
-  created() {
-    this.getMyUserInfo();
-  },
-  methods: {
-    getMyUserInfo() {
-      GetMyUserInfo().then((res) => {
-        this.userInfo = res;
-      });
-    },
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.user-info {
-  padding: 24px;
-}
-</style>

+ 1 - 1
vue.config.js

@@ -58,7 +58,7 @@ module.exports = defineConfig({
     },
   },
   configureWebpack: {
-    name: '教材编辑器',
+    name: '智慧梧桐桌面端互动教材编辑器',
     // 配置路径别名
     resolve: {
       alias: {