写一个uniapp的登录注册页面

server/2024/12/22 9:05:10/

目录

一、效果图

二、代码

1、登录

(1)页面布局代码

(2)逻辑实现代码

(3)css样式

2、注册

(1)页面布局代码

(2)逻辑实现代码

(3)css样式

3、接口(所有用到的js)

(1)login.js

(2)request.js

(3)auth.js

(4)common.js

(5)crpto.js

(6)jsencrypt.js

(7)errorCode.js

(8)config.js


一、效果图

二、代码

1、登录
(1)页面布局代码
<template><view class="normal-login-container"><view class="logo-content align-center justify-center flex"><image class="img-a" src="/static/images/b-1.png"></image><image class="img-b" src="/static/images/b-2.png"></image><!-- 标题 --><view class="text"><view class="t-b">{{ title }}</view><view class="t-b2">{{ subTitle }}</view></view></view><view class="login-form-content"><view class="input-item flex align-center"><view class="iconfont icon-user icon"></view><input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" /></view><view class="input-item flex align-center"><view class="iconfont icon-password icon"></view><input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" /></view><view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled"><view class="iconfont icon-code icon"></view><input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" /><view class="login-code"> <image :src="codeUrl" @click="getCode" class="login-code-img"></image></view></view><view class="action-btn"><button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button></view><view class="reg text-center" v-if="register"><text class="text-grey1">没有账号?</text><text @click="handleUserRegister" class="text-blue">立即注册</text></view><view class="xieyi text-center"><!-- <text class="text-grey1">登录即代表同意</text><text @click="handleUserAgrement" class="text-blue">《用户协议》</text><text @click="handlePrivacy" class="text-blue">《隐私协议》</text> --></view></view></view>
</template>
(2)逻辑实现代码
<script>import { getCodeImg } from '@/api/login'export default {data() {return {title: '管理平台',subTitle: '欢迎回来,开始工作吧!',codeUrl: "",captchaEnabled: true,// 用户注册开关register: true,globalConfig: getApp().globalData.config,loginForm: {username: "admin",password: "admin123",code: "",uuid: ''}}},created() {this.getCode()},methods: {// 用户注册handleUserRegister() {this.$tab.redirectTo(`/pages/register`)},// 隐私协议// handlePrivacy() {//   let site = this.globalConfig.appInfo.agreements[0]//   this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)// },// // 用户协议// handleUserAgrement() {//   let site = this.globalConfig.appInfo.agreements[1]//   this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)// },// 获取图形验证码getCode() {getCodeImg().then(res => {res=res.datathis.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabledif (this.captchaEnabled) {this.codeUrl = 'data:image/gif;base64,' + res.imgthis.loginForm.uuid = res.uuid}})},// 登录方法async handleLogin() {if (this.loginForm.username === "") {this.$modal.msgError("请输入您的账号")} else if (this.loginForm.password === "") {this.$modal.msgError("请输入您的密码")} else if (this.loginForm.code === "" && this.captchaEnabled) {this.$modal.msgError("请输入验证码")} else {this.$modal.loading("登录中,请耐心等待...")this.pwdLogin()}},// 密码登录async pwdLogin() {this.$store.dispatch('Login', this.loginForm).then(() => {// console.log(document.response);this.$modal.closeLoading()this.loginSuccess()}).catch(() => {if (this.captchaEnabled) {this.getCode()}})},// 登录成功后,处理函数loginSuccess(result) {// 设置用户信息this.$store.dispatch('GetInfo').then(res => {this.$tab.reLaunch('/pages/index')})}}}
</script>

(3)css样式
<style lang="scss">page {background-color: #ffffff;}.normal-login-container {width: 100%;.logo-content {width: 100%;font-size: 21px;text-align: center;padding-top: 15%;image {border-radius: 4px;}.title {margin-left: 10px;}}.login-form-content {text-align: center;margin: 20px auto;// margin-top: 3%;width: 80%;.input-item {margin: 20px auto;background-color: #f5f6f7;height: 45px;border-radius: 20px;.icon {font-size: 38rpx;margin-left: 10px;color: #999;}.input {width: 100%;font-size: 14px;line-height: 20px;text-align: left;padding-left: 15px;}}.login-btn {margin-top: 40px;height: 45px;}.reg {margin-top: 15px;}.xieyi {color: #333;margin-top: 20px;}.login-code {height: 38px;float: right;.login-code-img {height: 38px;position: absolute;margin-left: 10px;width: 200rpx;}}}}
.img-a {position: absolute;width: 100%;top: -74px;right: 0;z-index: 100;
}
.img-b {position: absolute;width: 50%;bottom: 0;left: -50rpx;z-index: 100;
}
.text{margin-left: -111px;margin-top: 28px;
}
.t-b {text-align: left;font-size: 29px;color: #000;padding: 60px 0 10px 0;font-weight: bold;
}
.t-b2 {text-align: left;font-size: 32rpx;color: #aaaaaa;padding: 0rpx 0 60rpx 0;
}</style>
2、注册
(1)页面布局代码
<template><view class="normal-login-container"><view class="logo-content align-center justify-center flex"><!-- <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix"></image> --><image class="img-a" src="/static/images/b-1.png"></image><image class="img-b" src="/static/images/b-2.png"></image><text class="title">绣创科技移动端注册</text></view><view class="login-form-content"><view class="input-item flex align-center"><view class="iconfont icon-user icon"></view><input v-model="registerForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" /></view><view class="input-item flex align-center"><view class="iconfont icon-password icon"></view><input v-model="registerForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" /></view><view class="input-item flex align-center"><view class="iconfont icon-password icon"></view><input v-model="registerForm.confirmPassword" type="password" class="input" placeholder="请输入重复密码" maxlength="20" /></view><view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled"><view class="iconfont icon-code icon"></view><input v-model="registerForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" /><view class="login-code"> <image :src="codeUrl" @click="getCode" class="login-code-img"></image></view></view><view class="action-btn"><button @click="handleRegister()" class="register-btn cu-btn block bg-blue lg round">注册</button></view></view><view class="xieyi text-center"><text @click="handleUserLogin" class="text-blue">使用已有账号登录</text></view></view>
</template>
(2)逻辑实现代码
<script>import { getCodeImg, register } from '@/api/login'export default {data() {return {codeUrl: "",captchaEnabled: true,globalConfig: getApp().globalData.config,registerForm: {username: "",password: "",confirmPassword: "",code: "",uuid: '',userType:"app_user"}}},created() {this.getCode()},methods: {// 用户登录handleUserLogin() {this.$tab.navigateTo(`/pages/login`)},// 获取图形验证码getCode() {getCodeImg().then(res => {this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabledif (this.captchaEnabled) {this.codeUrl = 'data:image/gif;base64,' + res.data.imgthis.registerForm.uuid = res.data.uuid}})},// 注册方法async handleRegister() {if (this.registerForm.username === "") {this.$modal.msgError("请输入您的账号")} else if (this.registerForm.password === "") {this.$modal.msgError("请输入您的密码")} else if (this.registerForm.confirmPassword === "") {this.$modal.msgError("请再次输入您的密码")} else if (this.registerForm.password !== this.registerForm.confirmPassword) {this.$modal.msgError("两次输入的密码不一致")} else if (this.registerForm.code === "" && this.captchaEnabled) {this.$modal.msgError("请输入验证码")} else {this.$modal.loading("注册中,请耐心等待...")this.register()}},// 用户注册async register() {register(this.registerForm).then(res => {this.$modal.closeLoading()uni.showModal({title: "系统提示",content: "恭喜你,您的账号 " + this.registerForm.username + " 注册成功!",success: function (res) {if (res.confirm) {uni.redirectTo({ url: `/pages/login` });}}})}).catch(() => {if (this.captchaEnabled) {this.getCode()}})},// 注册成功后,处理函数registerSuccess(result) {// 设置用户信息this.$store.dispatch('GetInfo').then(res => {this.$tab.reLaunch('/pages/index')})}}}
</script>
(3)css样式
<style lang="scss">page {background-color: #ffffff;}.normal-login-container {width: 100%;.logo-content {width: 100%;font-size: 21px;text-align: center;padding-top: 15%;image {border-radius: 4px;}.title {margin-left: 10px;position: absolute;z-index: 100;}}.login-form-content {text-align: center;margin: 20px auto;margin-top: 30%;width: 80%;.input-item {margin: 20px auto;background-color: #f5f6f7;height: 45px;border-radius: 20px;.icon {font-size: 38rpx;margin-left: 10px;color: #999;}.input {width: 100%;font-size: 14px;line-height: 20px;text-align: left;padding-left: 15px;}}.register-btn {margin-top: 40px;height: 45px;}.xieyi {color: #333;margin-top: 20px;}.login-code {height: 38px;float: right;.login-code-img {height: 38px;position: absolute;margin-left: 10px;width: 200rpx;}}}}
.img-a {position: absolute;width: 100%;top: -74px;right: 0;z-index: 100;
}
.img-b {position: absolute;width: 50%;bottom: 0;left: -50rpx;z-index: 100;
}
</style>
3、接口(所有用到的js)
(1)login.js
import request from '@/utils/request'// 登录方法
export function login(username, password, code, uuid) {const data = {username,password,code,uuid}return request({'url': '/login',headers: {isToken: false},'method': 'post','data': data})
}// 注册方法
export function register(data) {return request({url: '/register',headers: {isToken: false},method: 'post',data: data})
}// 获取用户详细信息
export function getInfo() {return request({'url': '/getInfo','method': 'get'})
}// 退出方法
export function logout() {return request({'url': '/logout','method': 'post'})
}// 获取验证码
export function getCodeImg() {return request({'url': '/captchaImage',headers: {isToken: false},method: 'get',timeout: 20000})
}
(2)request.js
import store from '@/store'
import config from '@/config'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { toast, showConfirm, tansParams } from '@/utils/common'
import { encryptBase64, encryptWithAes, generateAesKey } from '@/utils/crypto';
import { encrypt } from '@/utils/jsencrypt';let timeout = 10000
const baseUrl = config.baseUrl
const clientId = config.clientIdconst request = config => {// 是否需要设置 tokenconst isToken = (config.headers || {}).isToken === falseconfig.header = config.header || {}if (getToken() && !isToken) {config.header['Authorization'] = 'Bearer ' + getToken()}config.header['clientid']=clientId// get请求映射params参数if (config.params) {let url = config.url + '?' + tansParams(config.params)url = url.slice(0, -1)config.url = url}// 是否需要加密const isEncrypt = (config.headers || {}).isEncrypt === true;// 当开启参数加密if (isEncrypt && (config.method === 'post' || config.method === 'put')) {// 生成一个 AES 密钥const aesKey = generateAesKey();config.header['encrypt-key'] = encrypt(encryptBase64(aesKey));config.data = typeof config.params === 'object' ? encryptWithAes(JSON.stringify(config.params), aesKey) : encryptWithAes(config.params, aesKey);}return new Promise((resolve, reject) => {uni.request({method: config.method || 'get',timeout: config.timeout ||  timeout,url: config.baseUrl || baseUrl + config.url,data: config.data,header: config.header,dataType: 'json'}).then(response => {let [error, res] = responseif (error) {toast('后端接口连接异常')reject('后端接口连接异常')return}const code = res.data.code || 200const msg = errorCode[code] || res.data.msg || errorCode['default']if (code === 401) {showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {if (res.confirm) {store.dispatch('LogOut').then(res => {uni.reLaunch({ url: '/pages/login' })})}})reject('无效的会话,或者会话已过期,请重新登录。')} else if (code === 500) {toast(msg)reject('500')} else if (code !== 200) {toast(msg)reject(code)}resolve(res.data)}).catch(error => {let { message } = errorif (message === 'Network Error') {message = '后端接口连接异常'} else if (message.includes('timeout')) {message = '系统接口请求超时'} else if (message.includes('Request failed with status code')) {message = '系统接口' + message.substr(message.length - 3) + '异常'}toast(message)reject(error)})})
}export default request
(3)auth.js
const TokenKey = 'App-Token'export function getToken() {return uni.getStorageSync(TokenKey)
}export function setToken(token) {return uni.setStorageSync(TokenKey, token)
}export function removeToken() {return uni.removeStorageSync(TokenKey)
}
(4)common.js
/**
* 显示消息提示框
* @param content 提示的标题
*/
export function toast(content) {uni.showToast({icon: 'none',title: content})
}/**
* 显示模态弹窗
* @param content 提示的标题
*/
export function showConfirm(content) {return new Promise((resolve, reject) => {uni.showModal({title: '提示',content: content,cancelText: '取消',confirmText: '确定',success: function(res) {resolve(res)}})})
}/**
* 参数处理
* @param params 参数
*/
export function tansParams(params) {let result = ''for (const propName of Object.keys(params)) {const value = params[propName]var part = encodeURIComponent(propName) + "="if (value !== null && value !== "" && typeof (value) !== "undefined") {if (typeof value === 'object') {for (const key of Object.keys(value)) {if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {let params = propName + '[' + key + ']'var subPart = encodeURIComponent(params) + "="result += subPart + encodeURIComponent(value[key]) + "&"}}} else {result += part + encodeURIComponent(value) + "&"}}}return result
}
(5)crpto.js
import CryptoJS from 'crypto-js';/*** 随机生成32位的字符串* @returns {string}*/
export function generateRandomString(){const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';let result = '';const charactersLength = characters.lengthfor (let i = 0; i < 32; i++) {result += characters.charAt(Math.floor(Math.random() * charactersLength));}return result
}/*** 随机生成aes 密钥* @returns {string}*/
export function generateAesKey(){return CryptoJS.enc.Utf8.parse(generateRandomString());
}/*** 加密base64* @returns {string}*/
export function encryptBase64(str){return CryptoJS.enc.Base64.stringify(str);
}/*** 使用密钥对数据进行加密* @param message* @param aesKey* @returns {string}*/
export function encryptWithAes(message, aesKey){const encrypted = CryptoJS.AES.encrypt(message, aesKey, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});return encrypted.toString();
}
(6)jsencrypt.js
import JSEncrypt from 'jsencrypt';
// 密钥对生成 http://web.chacuo.net/netrsakeypairconst publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';// 前端不建议存放私钥 不建议解密数据 因为都是透明的意义不大
const privateKey = '**********';// 加密
export function encrypt(txt){const encryptor = new JSEncrypt();encryptor.setPublicKey(publicKey); // 设置公钥return encryptor.encrypt(txt); // 对数据进行加密
};// 解密
export function decrypt(txt){const encryptor = new JSEncrypt();encryptor.setPrivateKey(privateKey); // 设置私钥return encryptor.decrypt(txt); // 对数据进行解密
};
(7)errorCode.js
export default {'401': '认证失败,无法访问系统资源','403': '当前操作没有权限','404': '访问资源不存在','default': '系统未知错误,请反馈给管理员'
}
(8)config.js
// 应用全局配置
module.exports = {baseUrl: 'http://localhost:8080',//根据实际更换//客户端idclientId:'...............',//授权模式grantType:'password',//租户idtenantId: '000000',//记住我模式rememberMe: false,// 应用信息appInfo: {// 应用名称name: "...",// 应用版本version: "1.1.0",// 应用logologo: "/static/logo.png",// 官方网站site_url: "...",// 政策协议agreements: [{title: "隐私政策",url: "..."},{title: "用户服务协议",url: "..."}]}
}


http://www.ppmy.cn/server/3805.html

相关文章

XTuner 微调介绍

本文主要简单介绍微调地基础知识&#xff0c;以及开源微调框架 XTuner的使用。 一. 微调简介 1. Finetune范式 当我们想要在别人地预训练模型上得到我们想要地能力时&#xff0c;通常我们有两种微调方式&#xff1a; 1. 增量预训练微调 2. 指令跟随微调 2. 一条数据地一生 我…

14.JavaWeb深入理解Tomcat和Servlet

目录 导语&#xff1a; 一、Tomcat概述 1.下载 2.安装 3.卸载 4.启动 5.关闭 6.配置 二、Servlet概念 快速入门&#xff1a; 执行原理&#xff1a; 三、Tomcat和Servlet内容 四、案例&#xff1a;使用Tomcat和Servlet创建一个简单的Web应用程序 1.创建Servlet&am…

mysql面试题五(事务)

目录 1.mysql有哪些锁及作用 1. 行锁&#xff08;Row Locks&#xff09; 2. 间隙锁&#xff08;Gap Locks&#xff09; 3. Next-Key Locks 4. 意向锁&#xff08;Intention Locks&#xff09; 5. 表锁&#xff08;Table Locks&#xff09; 6. 元数据锁&#xff08;Metad…

海外媒体如何发布软文通稿

大舍传媒-带您了解海外发布新潮流 随着全球化的不断深入&#xff0c;越来越多的中国企业开始关注海外市场。为了在国际舞台上树立品牌形象&#xff0c;企业纷纷寻求与海外媒体合作&#xff0c;通过发布软文通稿的方式&#xff0c;传递正面信息&#xff0c;提升品牌知名度。作为…

chromedriver最新版下载地址

地址1.百度网盘 链接(提取码&#xff1a;2vo3)&#xff1a;百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com…

运动想象 (MI) 分类学习系列 (9) :FBCNet

运动想象分类学习系列:FBCNet 0. 引言1. 主要贡献2. 提出的方法2.1 滤波器组卷积网络2.2 方差层结构介绍 3. 实验结果3.1 基线方法比较3.2 方差层对结果的影响3.3 脑卒中患者在相关模型中观察到更大的受试间变异性 4. 总结欢迎来稿 论文地址&#xff1a;https://arxiv.org/abs/…

会议室预约小程序开源版开发

会议室预约小程序开源版开发 支持设置免费预约和付费预约、积分兑换商城、积分签到等 会议室类目&#xff0c;提供多种类型和设施的会议室选择&#xff0c;满足不同会议需求。 预约日历&#xff0c;展示会议室预约情况&#xff0c;方便用户选择空闲时段。 预约记录&#xff0…

使用undetected-chromedriver遇到的问题及解决方法,以及它使用SOCKS代理的问题

环境&#xff1a;python3.8.10 uc的安装方法&#xff1a; pip38 install undetected-chromedriver 上测试代码&#xff1a; import undetected_chromedriver as uc driver uc.Chrome() driver.get(https://www.baidu.com) driver.save_screenshot(baidu.png)报错&#xff…