往期开发(已经完成)

今日后端开发

  • 库表设计

    用户表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    -- 用户表
    create table if not exists user
    (
    id bigint auto_increment comment 'id' primary key,
    userAccount varchar(256) not null comment '账号',
    userPassword varchar(512) not null comment '密码',
    userName varchar(256) null comment '用户昵称',
    userAvatar varchar(1024) null comment '用户头像',
    userProfile varchar(512) null comment '用户简介',
    userRole varchar(256) default 'canUser' not null comment '用户角色:canUser/canAdmin/ban',
    createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete tinyint default 0 not null comment '是否删除'
    ) comment '用户' collate = utf8mb4_unicode_ci;

    题目表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
      -- -- 题目表
    create table if not exists question
    (
    id bigint auto_increment comment 'id' primary key,
    title varchar(512) null comment '标题',
    content text null comment '内容',
    tags varchar(1024) null comment '标签列表(json 数组)',
    answer text null comment '题目答案',
    submitNum int default 0 not null comment '提交数',
    acceptedNum int default 0 not null comment '题目通过数',
    judgeCase text null comment '判断原因',
    judgeConfig text null comment '判题配置',
    thumbNum int default 0 not null comment '点赞数',
    favourNum int default 0 not null comment '收藏数',
    userId bigint not null comment '创建用户 id',
    createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete tinyint default 0 not null comment '是否删除',
    index idx_userId (userId)
    ) comment '题目表' collate = utf8mb4_unicode_ci;

    题目提交表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    -- -- 题目提交表
    create table if not exists question_submit
    (
    id bigint auto_increment comment 'id' primary key,
    language varchar(128) not null comment '编程语言',
    code text not null comment '代码',
    judgeInfo text null comment '判题信息',
    status int default 0 not null comment '判题状态',
    questionId bigint not null comment '帖子 id',
    userId bigint not null comment '创建用户 id',
    createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    index idx_postId (questionId),
    index idx_userId (userId)
    ) comment '题目提交表';

    其中一些字段用 JSON 格式进行存储

    • 数据库的索引

      Q:什么情况下适合去使用索引增加查询效率?如何选择给那个字段进行增加索引?

      A:首先业务重发,无论是单个索引、还是联合索引,从实际的查询语句、字段枚举值的区分度。字段类型考虑即 where 条件指定字段

      E: where userId = 1 and question = 2,可以单独设立索引也可以做联合。

      原则上表数据少时候建议不添加索引,会导致 UPDATE、INSERT 执行效率变低,提高了查询效率,不能给没有区分度的字段添加索引比如男、女

      由于每次更新会更新索引当前列,添加会添加索引字段,删除会删除索引列,索引也是要占用空间

  • 判题信息的枚举

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Accepted 成功
    Wrong Answer 答案错误
    Compile Error 编译错误
    Memory Limit Exceeded 内存溢出
    Time Limit Exceeded 超时
    Presentation Error 展示错误
    Output Limit Exceeded 输出溢出
    Waiting 等待中
    Dangerous Operation 危险操作
    Runtime Error 运行错误 (用户程序的问题)
    System Error 系统错误
  • 使用 MyBatisPlus-X

    1. 功能设计库表完成
    2. 使用插件生成对应的 entity,mapper,service 代码
    3. 重构生成的代码到指定位置
    4. 对某些需要使用 JSON 格式存储的字段 进行单独的 vo 封装
    5. 在 entity 中 编写对应的 vo 和 entity 转换方法(脱敏)

今日前端开发

  • 自动登录

    • VueX 状态管理

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      actions: {
      async getLoginUser({ commit, state }) {
      try {
      const res = await UserControllerService.getLoginUserUsingGet();
      if (res.code == 0) {
      commit("updateUser", res.data);
      } else {
      commit("updateUser", {
      ...state.loginUser,
      userRole: ACCESS.NOT_LOGIN,
      });
      }
      } catch (e) {
      Message.error("获取登录信息失败!");
      }
      },
      },
      mutations: {
      updateUser(state, payload) {
      state.loginUser = payload;
      },
      }
  • 全局权限

    • 权限管理

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      import ACCESS from "@/access/access";
      import { LoginUserVO } from "@/service/chenoj-api";

      /**
      * 检查权限
      * @param loginUser 登录用户
      * @param needAccess 需要的权限
      * @return 是否可以
      */
      const checkAccess = (
      loginUser: LoginUserVO,
      needAccess = ACCESS.NOT_LOGIN
      ) => {
      const loginUserAccess = loginUser?.userRole ?? ACCESS.NOT_LOGIN;
      if (needAccess === ACCESS.NOT_LOGIN) {
      return true;
      }
      if (needAccess === ACCESS.USER) {
      return (
      loginUserAccess === ACCESS.USER || loginUserAccess === ACCESS.ADMIN
      );
      }
      if (needAccess === ACCESS.ADMIN) {
      return loginUserAccess === ACCESS.ADMIN;
      }
      return true;
      };
      export default checkAccess;

      全局权限检查

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      import router from "@/router";
      import store from "@/store";
      import ACCESS from "@/access/access";
      import checkAccess from "@/access/checkAccess";

      router.beforeEach(async (to, form, next) => {
      // 如果是去注册直接放行
      if (to.fullPath.includes("/user/register")) {
      next();
      }
      const loginUser = store.state.user.loginUser;
      if (!loginUser || !loginUser.userRole) {
      await store.dispatch("getLoginUser");
      }
      const isLoginUser = store.state.user.loginUser;
      // 如果未登录 则跳转到登录页面
      if (
      isLoginUser.userRole == ACCESS.NOT_LOGIN ||
      isLoginUser.userName == "未登录"
      ) {
      if (!to.fullPath.includes("/user/login")) {
      next(`/user/login?redirect=${to.fullPath}`);
      } else {
      next();
      }
      return;
      }
      // 登录就要确定权限是什么 获取权限
      const needAccess = to.meta.access;
      // 如果登录成功 就做校验
      if (checkAccess(store.state.user.loginUser, needAccess as string)) {
      next();
      return;
      }
      next("/404");
      });
  • 使用组件进行登录、注册页面开发

    注册页

    登录页