欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【景途无忧微信小程序】——零基础手把手带你实现,既能连接数据库,又能实现多项功能的前后端交互的微信小程序设计(上)

【景途无忧微信小程序】——零基础手把手带你实现,既能连接数据库,又能实现多项功能的前后端交互的微信小程序设计(上)

2025/6/22 23:58:10 来源:https://blog.csdn.net/shsjssnn/article/details/144752743  浏览:    关键词:【景途无忧微信小程序】——零基础手把手带你实现,既能连接数据库,又能实现多项功能的前后端交互的微信小程序设计(上)

🎼个人主页:【Y小夜】

😎作者简介:一位双非学校的大三学生,编程爱好者,

专注于基础和实战分享,欢迎私信咨询!

🎆入门专栏:🎇【MySQL,Java基础,Rust】

🎈热门专栏:🎊【Python,Javaweb,Springboot】 

感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️

目录

🎈项目背景

🎊需求分析

🎊性能需求

🎊功能需求

🎈登录功能

🎊创建数据库

🎊后台服务端

🎄初始化服务端

🎄功能实现

🎁utils文件夹

 🎁routers文件夹

 🎁app.js文件

 🎄测试功能

🎊前台微信小程序

🎄功能实现

 🎁index.html

 🎁index.js

🎄 页面展示

🎈注册功能

🎊后台服务端

🎊前端服务端

🎄功能实现

 🎁regist.js

🎁regist.wxml

🎄页面展示


🎈项目背景

🎊需求分析

        在当今这个快节奏、高互联的时代,旅游已不仅仅是简单的出行,它更是一种生活方式的探索与体验。随着科技的进步和人们生活品质的提升,现代旅行者对旅游服务的需求日益多元化和个性化。他们渴望在旅途中不仅能够享受到便捷的预订服务,还希望能获得深度的文化体验、实时的信息更新以及社交互动的乐趣。因此,设计一款集景区展示、购票服务、景点推荐、AI答疑等功能于一体的微信小程序“景途无忧”,显得尤为迫切和必要。

🎊性能需求

  • 正确性需求

管理员应能够进行有关的旅游信息准确地添加到数据库中。系统用户登录后,系统应能正确地读取用户个人信息。系统的操作结果与预期的结果应该是一致。

  • 安全性需求

无重大安全漏洞,用户数据得到妥善保护。

  • 及时性需求

即时可见:对旅游信息的处理(包括添加、删除、修改)将立即在后台数据库中进行更新,达到“即时操作、即时生效”的功能

  • 稳定性需求

系统部署后,在硬件条件和支持软件条件没有变化的情况下,能够一直保持运行状态,直到系统被升级或代替。

  • 扩展性需求

系统应该支持功能扩展与支持环境的扩展。功能扩展就是在现有的功能模块的基础上可以添加信息的功能模块。

  • 故障处理能力需求

系统可能遇到的软件故障是数据库与应用程序服务器。为了满足信息处理的需求,可以采取数据恢复来解决。

🎊功能需求

  •         运行景途无忧小程序后,进入登录/注册页面,用户如已有账号,可以直接输入账号和密码进行登录,若无账号,可以先进行注册,然后再进行登录操作。
  •         首页对数据库中的景点数据进行展示,并且用户可以根据景点名称对感兴趣的景点进行搜索,用户也可以对景点的门票进行购买,加入订单中。
  •         小助手页面是调用智能云平台创建的旅游小助手智能体,用于对用户提出的关于旅游的问题进行回答。
  •         订单页面可以查看自己购买的门票,并且可以对订单进行取消操作。
  •         我的页面用户可以进行查看个人信息、快速注册、退出登录或查看关于我们的界面

🎈登录功能

🎊创建数据库

先自己创建一个MySQL的tour数据库

🎊后台服务端

🎄初始化服务端

先自己创建一个文件夹,用于存放服务端代码

然后开始搭建服务器

  • 下载Node.js(https://nodejs.org),选择长期支持版下载。
  • 安装Node.js,双击下载的安装包安装即可,安装选项全部使用默认值。
  • “用户登录”文件夹下创建文件夹“服务器端”来存放小程序项目对应的服务器端文件。
  • “服务器端”文件夹下进入DOS命令界面。
  • 初始化服务器端项目,将会自动创建package.json配置文件。    npm init  -y
  • 安装Express框架,用于快速搭建HTTP服务器。 npm install express  --save
  • 安装request模块。npm install request  --save
  • 安装nodemon监控代码修改。 npm install nodemon  -g

安装完之后再在根目录下创建一个app.js文件,如下图

最后使用vscode将自己创建的文件加打开

🎄功能实现

🎁utils文件夹

首先,在根目录下创建utils文件夹

在utils文件夹下创建BaseDB.js文件用于导入MySQL的模块

//导入mysql的模块
const mysql=require("mysql")
//创建数据库连接
const db=mysql.createConnection({//数据库的主机地址host:"localhost",//数据库账号user:"root",//数据库密码password:"密码",//操作的目标数据库database:"数据库名"
})
//导出数据库连接对象
module.exports=db

在utils文件夹下创建Result.js文件用于封装结果类

//定义Result结果封装类
class Result{//返回成功的对象的方法static success(data){//返回结果return{code:0,msg:"成功",data:data}}//返回失败时的对象的方法static fail(data){return{code:1,msg:"失败",data:data}}
}
module.exports=Result
 🎁routers文件夹

在routers文件下创建userRouter.js文件,开始编写用户登陆的功能

//导入express用模块
const express=require("express")
//导入获得路由实例
const router=express.Router()
//导入数据库连接对象
const db=require("../utils/BaseDB")
//导入结果封装类
const Result=require("../utils/Result")//用户登录
router.post('/user/login',(req,resp)=>{//获取用户名和密码let username=req.body.usernamelet password=req.body.password//定义sql语句let sql=`select * from user where username=? and password=?`//定义参数let params=[username,password]//查询数据库db.query(sql,params,(err,res)=>{//错误if(err){resp.send(Result.fail(err))}else{//成功resp.send(Result.success(res))}})
})
//进行导出
module.exports=router
 🎁app.js文件

在app.js文件中编写代码,将路由引入

//导入express模块
const express = require('express')
//创建express的实例
const app=express()
//解析提交的json数据
app.use(express.json())
//解析提交表单的的数据
app.use(express.urlencoded({extended:true}))
//导入用户模块
const userRouter=require('./routers/userRouter')//配置路由
app.use(userRouter)// 监听3000端口
app.listen(3000,()=>{console.log("服务端启动成功.....")
})

 🎄测试功能

先打开终端,再根目录下使用node app 命令运行程序,但是不出意外的话这里要出意外了,请看下图报错

这里是意思是指没有引入mysql模块,我们查看一下node_modules文件夹,发现确实没有mysql

这时我们可以在终端使用 npm install mysql 命令下载mysql模块

下载完毕后,再次运行,发现运行成功。

        但是使用node命令运行,当代码发生改变时,页面并不会自动刷新。所以我们可以使用nodemon,nodemon可以实现对代码的监控,使得当代码更新时,不需要重启服务器,就可以自动更新代码。

使用npm install -g nodemon

 然后我们使用nodemon app运行,这时候可能还会出现一种错误,如下图

解决方案:

先使用管理员身份登录vscode

  1. 在终端运行:get-ExecutionPolicy,显示Restricted(表示状态是禁止的)
  2. 在终端执行,set-ExecutionPolicy RemoteSigned
  3. 在终端运行:get-ExecutionPolicy,显示RemoteSigned
  4. 再次运行nodemon app就可不会报错了

接下来使用apifox进行登录测试

请求:

响应:

到此我们的登录接口测试成功。

🎊前台微信小程序

🎄功能实现

 🎁index.html
<!-- 登录界面 -->
<view class="one">景途无忧</view>
<view class="conent"><view class="field"><view class="title">账号</view><view><input type="text" bind:input="usernameInput"placeholder="请输入账号"/></view></view><view class="hr"></view><view class="field"><view class="title">密码</view><view><input password="{{true}}" bind:blur="pwdBlur" placeholder="请输入密码"/></view></view><view class="hr"></view><view class="btns"><button type="primary" bind:tap="login" disabled="{{disabled}}">登陆</button><button type="default" bind:tap="regist">注册</button></view>
</view><!-- 重影 -->
<view class="shadow shadow-1"></view><view class="shadow shadow-2"></view>
<view class="two">在这里,我们致力于为您提供一个无忧无虑的旅行体验。无论您是想要探索美丽的自然风光,还是体验丰富的文化之旅,景途无忧都能满足您的需求。我们深知旅行中的每一个细节都至关重要,因此,从购票、规划行程到应对突发情况,我们都为您提供全方位的保障和支持。选择景途无忧,让我们一起开启一段美好的旅程吧!</view>
 🎁index.js
// 登录界面的js
//获取全局的app对象
const app = getApp()Page({data: {disabled:true,username:"",password:""},//账号文本框输入事件usernameInput(e){//获取当前输入的账号let username = e.detail.valueif(username){//让登陆按钮处于启用状态this.setData({disabled:false,username:username})}else{this.setData({disabled:true,username:username})}},//绑定密码的失焦函数pwdBlur(e){//将密码框中的数据,设置到data.password上this.setData({password:e.detail.value})},//点击登陆按钮login(e){let that=this//判断是否输入密码if(!this.data.password){wx.showToast({title: '请输入密码',icon:"error"})return}//发起服务端请求,进行登陆操作wx.request({//请求地址url:app.globalData.baseUrl+'/user/login',//请求方法method:"POST",//提交到后端的数据data:{"username":this.data.username,"password":this.data.password},success:(res)=>{//请求成功之后,获取后端响应的结果if(res.data.code==0 &&res.data.data.length>0){wx.showToast({title: '登陆成功',icon:"success"})//设置全局用户名app.globalData.username=that.data.username//登陆成功,将用户数据,存储到本地//跳转到商品首页setTimeout(()=>{wx.switchTab({url: '/pages/home/home',})},200)}else{wx.showToast({title: '登陆失败',icon:"error"})}}})},//注册事件// 导航到注册regist(e){wx.navigateTo({url: '/pages/regist/regist',})},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函数--监听页面隐藏*/onHide() {},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
})

🎄 页面展示

🎈注册功能

🎊后台服务端

// 用户注册
router.post('/user/regist', (req, resp) => {console.log(req.body);//获取获取一系列信息const { username, password, phone, address } = req.body;//定义sql语句let sql = `insert into user(username,password,phone,address) values(?,?,?,?)`;//定义参数let params = [username, password, phone, address];//执行sql语句db.query(sql, params, (err, res) => {//错误if (err) {resp.send(result.fail(err));}//成功else {resp.send(result.success(res));}});
});

🎊前端服务端

🎄功能实现

 🎁regist.js
// pages/regist/regist.js
const app=getApp();Page({/*** 页面的初始数据*/data: {username: "",password: "",phone: "",address: "",region: ['河南省', '洛阳市', '涧西区'],customItem: '全部'},// 绑定账号输入bindUsernameInput: function(e) {this.setData({username: e.detail.value});},// 绑定密码输入bindPasswordInput: function(e) {this.setData({password: e.detail.value});},// 绑定电话输入bindPhoneInput: function(e) {this.setData({phone: e.detail.value});},// 改变地区bindRegionChange: function(e) {this.setData({region: e.detail.value// 更新地址为选中的地区});},regist(e) {const { username, password, phone, region } = this.data;// 由于picker组件的值是数组,我们需要将其转换为字符串const address = region.join('');// 查看表格是否为空if (!username || !password || !phone || !address) {wx.showToast({title: '请填写完整信息',icon: 'error'});return;}// 提交数据wx.request({url: app.globalData.baseUrl + "/user/regist",method: "POST",data:{"username":username,"password":password,"phone":phone,"address":address},success: (res) => {if ((res.data.code==0)) {wx.showToast({title: '注册成功',icon: "success",});setTimeout(() => {wx.redirectTo({url: '/pages/index/index',});}, 100); // 0.1秒后跳转} else {wx.showToast({title: '注册失败',icon: 'error'});}}});}
});
🎁regist.wxml
<!--pages/regist/regist.wxml-->
<form bindsubmit="regist"><view class="conent"><view class="field"><view class="title">账号</view><view><input type="text" name="username" placeholder="请输入账号" bindinput="bindUsernameInput"/></view></view><view class="hr"></view><!-- 密码 --><view class="field"><view class="title">密码</view><view><input password="{{true}}" name="password" placeholder="请输入密码" bindinput="bindPasswordInput"/></view></view><view class="hr"></view><!-- 电话号 --><view class="field"><view class="title">电话</view><view><input type="text" name="phone" placeholder="请输入手机号" bindinput="bindPhoneInput"/></view></view><view class="hr"></view><view class="field"><view class="title">地址</view><picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}"><view class="picker">{{region[0]}},{{region[1]}},{{region[2]}}</view></picker></view><view class="hr"></view><button  class="btns" form-type="submit">注册</button>
</view>
</form>

🎄页面展示

 今天的讲解就到这里,预知后续如何,请看下篇文章!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词