TDesign中后台管理系统-用户登录
目录
- 1 创建用户表
- 2 开发后端接口
- 3 测试接口
- 4 修改登录页面调用后端接口
- 最终效果
- 总结
中后台系统第一个要实现的功能就是登录了,我们通常的逻辑是让用户在登录页面输入用户名和密码,调用后端接口去验证用户的合法性,然后根据接口返回的结果进行进一步的路由。本篇我们就介绍一下用户登录功能的开发过程。
1 创建用户表
用户表的话我们设计两个字段,用户名和密码,建表语句如下
CREATE TABLE `users` (`id` int(0) NOT NULL AUTO_INCREMENT,`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
2 开发后端接口
后端我们使用express框架,把涉及到用户的接口单独拆分到user.js中。打开后端的工程,新建一个user.js文件

因为需要给密码加密,我们引入一个加密的包,在Terminal里输入安装命令
npm install bcryptjs --save

在验证用户名和密码都正确后,给前端返回一个token,我们需要安装支持token的包
npm install jsonwebtoken --save

后端接口需要解析json数据,需要安装json解析包
npm install body-parser --save

包安装好了之后,在user.js中贴入如下代码,来验证用户名和密码
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
// 创建 MySQL 连接池
const pool = require('./database');
// 用户登录
router.post('/login', (req, res) => {const { username, password } = req.body;console.log(username, password)// 检查用户名是否存在pool.query('SELECT * FROM users WHERE username = ?', [username], (error, results) => {if (error) throw error;console.log(results)if (results.length === 0) {res.status(401).json({ code: 401, message: 'Invalid username or password' });} else {const user = results[0];// 验证密码是否匹配bcrypt.compare(password, user.password, (err, result) => {if (err) throw err;console.log("验证密码", result)if (result) {// 生成 JWT 令牌const token = jwt.sign({ id: user.id, username: user.username }, 'your_secret_key', { expiresIn: '1h' });res.status(200).json({ code: 200, message: "登录成功", data: token });} else {res.status(401).json({ code: 401, message: 'Invalid username or password' });}});}});
});module.exports = router;
然后在index.js里注册用户路由
const express = require('express');
const app = express();
const cors = require('cors');
const menuROuter = require('./menu')
const userRoutes = require('./user');
const bodyParser = require('body-parser');
// 定义路由
app.use(bodyParser.json());
app.get('/', (req, res) => {res.send('Hello, World!');
});
app.use(cors({origin: 'http://localhost:3002',credentials: true
}));
app.use('/api/get-menu-list',menuROuter);
app.use('/api/user',userRoutes);
// 启动服务器
app.listen(3000, () => {console.log('Server is running on port 3000');
});
3 测试接口
我们后端接口写好了之后需要进行测试,使用postman测试我们的接口

注意这里我们是post请求,body要选择json然后按照json的语法去构造参数,在Header里要设置我们的格式是json

4 修改登录页面调用后端接口
模板里给的是mock调用,我们需要真实的调用后端接口,找到store文件夹下的user.ts,改造登录方式为调用后端接口

import { defineStore } from 'pinia';import { usePermissionStore } from '@/store';
import type { UserInfo } from '@/types/interface';
import { login } from '@/api/login';const InitUserInfo: UserInfo = {name: '', // 用户名,用于展示在页面右上角头像处roles: [], // 前端权限模型使用 如果使用请配置modules/permission-fe.ts使用
};export const useUserStore = defineStore('user', {state: () => ({token: 'main_token', // 默认token不走权限userInfo: { ...InitUserInfo },}),getters: {roles: (state) => {return state.userInfo?.roles;},},actions: {async login(userInfo: Record<string, unknown>) {const res = await login(userInfo.account.toString(),userInfo.password.toString());if (res.code === 200) {this.token = res.data;} else {throw res;}},async getUserInfo() {const mockRemoteUserInfo = async (token: string) => {if (token === 'main_token') {return {name: 'Tencent',roles: ['all'], // 前端权限模型使用 如果使用请配置modules/permission-fe.ts使用};}return {name: 'td_dev',roles: ['UserIndex', 'DashboardBase', 'login'], // 前端权限模型使用 如果使用请配置modules/permission-fe.ts使用};};const res = await mockRemoteUserInfo(this.token);this.userInfo = res;},async logout() {this.token = '';this.userInfo = { ...InitUserInfo };},},persist: {afterRestore: () => {const permissionStore = usePermissionStore();permissionStore.initRoutes();},key: 'user',paths: ['token'],},
});
这里将调用后端接口的代码单独封装一下,在src/api目录下新建一个login.ts文件,输入如下代码

// store/actions.ts
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';export const login = (username: string, password: string): Promise<any> => {return new Promise((resolve, reject) => {const requestConfig: AxiosRequestConfig = {url: 'http://localhost:3000/api/user/login',method: 'post',data: {username,password,},headers: {'Content-Type': 'application/json',},};axios(requestConfig).then((response: AxiosResponse) => {const result = response.data;if (result.code === 200 && result.message === '登录成功') {resolve(result);} else {reject(new Error(result.message));}}).catch((error) => {reject(error);});});
};
我们使用axios库去请求后端接口,需要先安装一下库
npm install axios --save
代码写好之后,启动前后端项目
node index.js //启动后端项目命令
npm run dev //启动前端项目命令
最终效果

总结
我们本篇讲解了TDesign实现登录的过程,需要先创建用户表,然后编写后端登录代码,编写前端代码调用后端接口。
总体上流程并不复杂,主要是要熟悉axios库的用法即可。
相关文章:
TDesign中后台管理系统-用户登录
目录 1 创建用户表2 开发后端接口3 测试接口4 修改登录页面调用后端接口最终效果总结 中后台系统第一个要实现的功能就是登录了,我们通常的逻辑是让用户在登录页面输入用户名和密码,调用后端接口去验证用户的合法性,然后根据接口返回的结果进…...
RN 使用react-navigation写可以滚动的横向导航条(expo项目)
装包: yarn add react-navigation/material-top-tabs react-native-tab-view npx expo install react-native-pager-view import React from react import { View, Text, ScrollView, SafeAreaView } from react-native import { Icon } from ../../../../../compo…...
单例模式写法的总结(保证线程安全)
首先,单例模式分为饿汉模式和懒汉模式 单例模式有什么用呢? 可以保证在程序运行过程中,一个类只有一个实例,而且该实例易于供外界访问,从而方便的控制了实例个数,并节约系统资源。 例如:DataSource&#x…...
SQL Server 查询数据并汇总相关技巧 23.08.08
GROUPING 是一个聚合函数,它产生一个附加的列,当用 CUBE 或 ROLLUP 运算符添加行时,附加的列输出值为1,当所添加的行不是由 CUBE 或 ROLLUP 产生时,附加列值为0。 仅在与包含 CUBE 或 ROLLUP 运算符的 GROUP BY 子句相联系的选择…...
第一章 SpringBoot 介绍-最小配置
1. spring-boot web应用的最小配置 1.1 pom配置两个依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version></parent><depende…...
10-1_Qt 5.9 C++开发指南_Data Visualization实现数据三维显示
Data Visualization 是 Qt 提供的用于数据三维显示的模块。在 Qt 5.7 以前只有商业版才有此模块,而从Qt5.7 开始此模块在社区版本里也可以免费使用了。Data Visualization 用于数据的三维显示,包括三维柱状图、三维空间散点、三维曲面等。Data Visualiza…...
[保研/考研机试] KY87 鸡兔同笼 北京大学复试上机题 C++实现
描述 一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。 输入描述: 每组测试数据占1行,…...
Jmeter快捷方式和应用图标设置
很多人在安装Jmeter,安装到本机却没有icon,每次使用的时候,每次打开应用都要找目录,不太方便。 【解决问题】 使用bin路径下的一个.bat文件,创建快捷方式。 【操作步骤】 Step1、将Jmeter 安装bin路径下的jmeter.bat 发送快捷方…...
PHP sm4国密加密解密文件
<?php // 打开要加密的 PDF 文件 $sourceFilePath path/to/source.pdf; $encryptedFilePath path/to/encrypted.pdf; $decryptedFilePath path/to/decrypted.pdf;// 生成一个 AES 密钥(256 位) $key random_bytes(32);// 选择一个加密模式&#…...
CBCGPRibbon 添加Edit、Combox、Hyperlink控件
编辑框、下拉框、网址按钮等是我们常用的控件,对应的类是 CBCGPRibbonEdit CBCGPRibbonComboBox CBCGPRibbonHyperlink 使用实例如下: //Edit CBCGPRibbonEdit* pEdit new CBCGPRibbonEdit(2001, 200); pEdit->SetReadOnly(TRUE); …...
漫话拥塞控制:BBR 是个单流模型
概要(便于检索主题):单流,多流收敛,probe buffer 挤压带宽,maxbw-filter wnd。 我曾经经常说 BBR 是个单流模型,而不是多流收敛模型,也做过不少评论,最近在复听 IETF 的大会,在 IET…...
HTML详解连载(1)
HTML详解连载(1) HTML定义HTML 超文本标记语言标签语法注意拓展 HTML基本骨架解释VS Code 快速生成骨架:标签的关系父子关系(嵌套关系)兄弟关系(并列关系) 代码格式注释 标题标签标签名:h1-h6(双…...
最新版本2023UI千月影视APP源码 开源完美版前后端完美匹配 后端基于ThinkPHP框架
最新版本的2023UI千月影视APP源码是一款开源的完美版应用程序,具备前后端完美匹配的特点。该应用的后端开发基于ThinkPHP框架,这是一个广泛使用的PHP开发框架,具有稳定性和安全性方面的优势。 2023UI千月影视APP是一款提供电影、电视剧、综艺…...
centos7安装Docker详细步骤(无坑版教程)
一、安装前必读 在安装 Docker 之前,先说一下配置,我这里是Centos7 Linux 内核:官方建议 3.10 以上,3.8以上貌似也可。 注意:本文的命令使用的是 root 用户登录执行,不是 root 的话所有命令前面要加 sudo…...
Python入门自学进阶-Web框架——39、redis、rabbitmq、git——2
RabbitMQ的exchange,即交换机有不同的类型: 1.direct Exchange(直接交换机) 匹配路由键,只有完全匹配消息才会被转发 2.Fanout Excange(扇出交换机) 将消息发送至所有的队列 3.Topic Exchange(主题交换机) 将路由按模…...
了解IL汇编跳转语句
il代码, .assembly extern mscorlib {}.assembly Test{.ver 1:0:1:0}.module test.exe.method static void main() cil managed{.maxstack 5.entrypointldstr "Enter First Number"call void [mscorlib]System.Console::WriteLine (string)call string …...
JVM运行时五大数据区域详解
前言: java虚拟机再执行Java程序的时候把它所拥有的内存区域划分了若干个数据区域。这些区域有着不同的功能,各司其职。这些区域不但功能不同,创建、销毁时间也不同。有些区域为线程私有,如:每个线程都有自己的程序计数…...
Vuex 使用教程
Vuex 各子模块的内部结构及作用 这是vuex的内部代码结构,所有的子模块都是一样的 state:存放数据状态; action:指派 mutation ; mutation:修改state里面的状态; getter:侧重于对数据…...
springboot启动you will need to add ‘org.slf4j‘ to prefer-application-packages异常解决
摘自个人印象笔记2020-09-12内容:[https://app.yinxiang.com/fx/6c3c7d9d-d5e5-4e5b-b2a1-33d6f29c48a7](https://app.yinxiang.com/fx/6c3c7d9d-d5e5-4e5b-b2a1-33d6f29c48a7) 启动异常: Caused by: java.lang.IllegalArgumentException: LoggerFactory…...
云原生核心原则和特征
云原生(Cloud Native)是一种软件开发和部署方法论,旨在充分利用云计算的优势来构建和管理应用程序。云原生应用程序是专为在云环境中设计、构建和运行的应用程序。 以下是云原生的一些核心原则和特征: 微服务架构:云…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
