最近花了不少时间做了个微信小程序,期间遇到了挺多技术问题的,写个博客记录一下,我先上小程序使用图片!
1.进入小程序首先要登录才能添加行程和查看行程
2.登录成功后
3.首页日历日期是可点击,点击后是查看行程表红色是当前日期灰色是上月与下月日期(灰色不可点击)
4.对行程表的周一到周日进行添加与修改
5.添加行程
6.查看行程表
技术实现:日历日期的算法;服务器连接;数据库设计。
首先日历日期的算法我是看网上大佬的分享,我本人水平很菜!
简单的微信小程序日历组件的实现(附完整代码)-小程序开发-PHP中文网
其他的功能都是在这个日历功能上实现的,所以日历日期算法才是核心,非常感谢前辈的分享!
在这个日历的基础上在wxml里用三目运算符来判断当前日期和上月与这个月的日期
wxml的代码:
<view class="calendar">
<view class="tit">
<view class='pre' bindtap='gotoPreMonth'>{{'<'}}</view>
<view class='current'>{{currentYear}}年{{currentMonth}}月</view>
<view class='next' bindtap='gotoNextMonth'>{{'>'}}</view>
</view>
<view class='content'>
<view>日</view>
<view>一</view>
<view>二</view>
<view>三</view>
<view>四</view>
<view>五</view>
<view>六</view>
<!-- 打印数组中所有数字,用wxss来判断是灰还是黑,然后用bindtap加三目运算符实现黑的可以点击灰的不能点击,从js里调当前时间来实现当前时间为红色 -->
<view wx:for="{{allArr}}" class="{{item.month == 'current' ? '' : 'gray'}}" bindtap="{{item.month == 'current' ? 'gotoNewView' : ''}}" data-year="{{currentYear}}" data-month="{{currentMonth}}" data-date="{{item.date}}">
<text wx:if="{{item.isCurrentDate == true && rMonth == currentMonth && rYear == currentYear}}" style="color: red;">{{item.date}}</text>
<text wx:else>{{item.date}}</text>
</view>
</view>
</view>
wxss代码:
.calendar{
width: 100%;
}
.calendar .tit{
display: flex;
justify-content: center;
align-items: center;
font-size: 36rpx;
color: #2A2A2A;
padding: 40rpx 0;
}
.calendar .tit .current{
margin: 0 40rpx;
}
.calendar .content{
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
padding-left: 25rpx;
}
.calendar .content view{
width: 100rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
flex-shrink: 0;
font-size: 34rpx;
color: #2A2A2A;
/* background: rgb(224, 199, 199); */
margin: 14rpx 0;
}
.calendar .content .gray{
color: #999;
}
js代码:
Component({
/**
* 组件的属性列表
*/
properties:{
currentYear:{
type:Number,
value:new Date().getFullYear()
},
currentMonth:{
type:Number,
value:new Date().getMonth() + 1
}
},
/**
* 组件的初始数据
*/
data:{
currentMonthDateLen:0, //当月天数
preMonthDateLen:0, //当月中,上月多余天数
allArr:[], //当月所有数据
rDate:0,
rYear:0,
rMonth:0
},
ready(){
this.getAllArr()
},
/**
* 数组的方法列表
*/
methods:{
//获取某年某月总共多少天
getDateLen(year, month){
let actualMonth = month - 1;
let timeDistance = +new Date(year, month) - +new Date(year, actualMonth);
return timeDistance / (1000 * 60 * 60 * 24);
},
//获取某月1号是周几
getFirstDateWeek(year, month){
return new Date(year, month - 1, 1).getDay()
},
//上月 年、月
preMonth(year, month){
if(month == 1){
return {
year: --year,
month: 12
}
}else{
return{
year:year,
month:--month
}
}
},
//下月 年、月
nextMonth(year, month){
if(month == 12){
return{
year:++year,
month:1
}
}else{
return{
year:year,
month:++month
}
}
},
//获取当月数据,返回数组
getCurrentArr(){
this.isNow()
let currentMonthDateLen = this.getDateLen(this.data.currentYear, this.data.currentMonth) //获取当月天数
let currentMonthDateArr = []
if(currentMonthDateLen > 0){
for(let i = 1; i <= currentMonthDateLen; ++i){
currentMonthDateArr.push({
month:'current',
date:i,
// 判断今天为几号
isCurrentDate: i == this.data.rDate ? true : false,
})
}
}
this.setData({
currentMonthDateLen
})
return currentMonthDateArr
},
//获取当月中,上月多余数据,返回数组
getPreArr(){
let preMonthDateLen = this.getFirstDateWeek(this.data.currentYear, this.data.currentMonth) //当月1号是周几 == 上月残余天数
let preMonthDateArr = [] //定义空数组
if(preMonthDateLen > 0){
let{year, month} = this.preMonth(this.data.currentYear, this.data.currentMonth) //获取上月年、月
let date = this.getDateLen(year, month)
for(let i = 0; i < preMonthDateLen; ++i){
preMonthDateArr.unshift({ //尾部追加
month:'pre',
date:date
})
--date
}
}
this.setData({
preMonthDateLen
})
return preMonthDateArr
},
//获取当月中,下月多余数据,返回数组
getNextArr(){
let nextMonthDateLen = 42 - this.data.preMonthDateLen - this.data.currentMonthDateLen //下月多余天数
let nextMonthDateArr = [] //定义空数组
if(nextMonthDateLen > 0){
for(let i = 1; i <= nextMonthDateLen; ++i){
nextMonthDateArr.push({
month: 'next', //只是为了增加标识,区分当前月、上月
date: i,
})
}
}
return nextMonthDateArr
},
//整合当前所有数据
getAllArr(){
let preArr = this.getPreArr()
let currentArr = this.getCurrentArr()
let nextArr = this.getNextArr()
let allArr = [...preArr, ...currentArr, ...nextArr]
this.setData({
allArr
})
let sendObj = {
currentYear: this.data.currentYear,
currentMonth: this.data.currentMonth,
allArr: allArr
}
this.triggerEvent('sendObj', sendObj)
},
//点击上月
gotoPreMonth(){
let{year, month} = this.preMonth(this.data.currentYear, this.data.currentMonth)
this.setData({
currentYear: year,
currentMonth: month
})
this.getAllArr()
},
//点击下月
gotoNextMonth(){
let{year, month} = this.nextMonth(this.data.currentYear, this.data.currentMonth)
this.setData({
currentYear: year,
currentMonth: month
})
this.getAllArr()
},
isNow(){
let timestamp = Date.parse(new Date())
let date = new Date(timestamp)
this.setData({
rYear : date.getFullYear(),
rMonth : (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1),
rDate : date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
})
},
gotoNewView:function({currentTarget}){
let iYear = currentTarget.dataset.year
let iMonth = currentTarget.dataset.month
let iDate = currentTarget.dataset.date
let dateStr = iYear+"-"+iMonth+"-"+iDate
// 点击的日期为星期几
let dayOfWeek = new Date(dateStr).getDay()
// 调用全局变量app来判断是否登录
var app = getApp()
if(app.globalData.isLogin == true){ //已登录
if(dayOfWeek == 0){
// bindtap点击事件,传送到对应的星期行程表
wx.navigateTo({
url: '/view/Schedule/sunday/sunday',
})
} else if (dayOfWeek == 1) {
wx.navigateTo({
url: '/view/Schedule/monday/monday',
})
} else if (dayOfWeek == 2) {
wx.navigateTo({
url: '/view/Schedule/tuesday/tuesday',
})
} else if (dayOfWeek == 3) {
wx.navigateTo({
url: '/view/Schedule/wednesday/wednesday',
})
} else if (dayOfWeek == 4) {
wx.navigateTo({
url: '/view/Schedule/thursday/thursday',
})
} else if (dayOfWeek == 5) {
wx.navigateTo({
url: '/view/Schedule/friday/friday',
})
} else if (dayOfWeek == 6) {
wx.navigateTo({
url: '/view/Schedule/saturday/saturday',
})
}
}else{
wx.switchTab({
url: '/view/login/login',
})
}
}
}
})
连接服务器根据wx.request函数来获取http连接服务器的url,我在服务器放的是php脚本,作用是操作mysql实现查看和增添修改以及获取用户的openid。
小程序连接服务器上脚本的代码:
首先需要在app.js设置全局变量接收openid和判断用户状态为登录还是登出
App({
globalData:{
isLogin:false,
openid:'',
},
onLaunch: function () {
}
});
连接用户登录的php脚本:
Page({
data:{
nickName:'',
icon:'',
userCode:'',
hasLogin:'',
getOpenid:''
},
login(){
var app = getApp()
console.log('点击事件执行了')
wx.getUserProfile({
desc: '需要授权登录',
success:res=>{
app.globalData.isLogin=true
var user = res.userInfo
console.log(user)
console.log('登录成功')
this.setData({
nickName:user.nickName,
icon:user.avatarUrl,
hasLogin:app.globalData.isLogin
})
wx.login({
success:res=>{
var code = res.code
this.setData({
userCode:code
})
//连接服务器
wx.request({
url: 'http://www.mcflyuuuuu.top/wx_program/userLogin.php服务器上php脚本的路径',
data:{
code:this.data.userCode,
nickName:this.data.nickName,
},
success:res=>{
console.log(res)
// console.log(res.data.openid)
app.globalData.openid = res.data.openid
console.log(app.globalData.openid)
}
})
}
})
}
})
},
outLogin(){
var app = getApp()
app.globalData.isLogin = false
console.log('登录已退出')
this.setData({
hasLogin:app.globalData.isLogin
})
}
})
连接添加与修改的php脚本:
B站上有大佬分享的教程:【分享】如何使用小程序在服务器数据库中插入信息_哔哩哔哩_bilibili
Page({
//数据库表中属性
mfAttribute:function(e){
this.setData({
mFir:e.detail.value
})
},
msAttribute:function(e){
this.setData({
mSec:e.detail.value
})
},
afAttribute:function(e){
this.setData({
aFir:e.detail.value
})
},
asAttribute:function(e){
this.setData({
aSec:e.detail.value
})
},
//连接数据库的基本信息
dbLink:function(){
var app = getApp()
console.log(app.globalData.openid)
wx.request({
url: 'http://www.mcflyuuuuu.top/wx_program/insertRecord.php', //服务器地址(php文件)
// 传到服务器的数据
data:{
openid:app.globalData.openid,
dayOfWeek:"星期一",
mFir:this.data.mFir,
mSec:this.data.mSec,
aFir:this.data.aFir,
aSec:this.data.aSec
},
success:function(res){
console.log(res)
}
})
wx.showLoading({
title: 'inserting',
})
setTimeout(function (){
wx.hideLoading()
wx.showToast({
title: 'success',
})
},1500)
}
})
这样的还有六个,然后dayOfWeek对应不同的星期,其他的都不变
连接查看行程表的php脚本:
Page({
data: {
},
/**
* 生命周期函数--监听页面加载
*/
//小程序Page中自带的onLoad函数
onLoad: function (options) {
var app = getApp()
wx.request({
url: '你的服务器上的php脚本路径',
data:{
openid:app.globalData.openid,
dayOfWeek:"星期一",
},
success: result=>{
console.log(result)
this.setData({
scheduleData:result.data.daySchedule,
})
}
})
}
})
对应的wxml代码
<text style="display: flex;flex-direction: column;align-items: center;">星期一</text>
<view wx:for="{{scheduleData}}">
<view class='mFir'>{{item.mFir}}</view>
<view class="mSec">{{item.mSec}}</view>
<view class="aFir">{{item.aFir}}</view>
<view class="aSec">{{item.aSec}}</view>
</view>
php脚本:
用户登录:
<?php
$code = $_GET['code'];
$nickName = $_GET['nickName'];
//调用jscode2session接口获取用户的openid
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid=‘小程序appid要去官网去查’&js_code=' . $code . '&grant_type=authorization_code';
//取出网页上的信息,信息为json格式
$info = file_get_contents($url);
//解析json
$json = json_decode($info);
$arr = get_object_vars($json);
$openid = $arr['openid'];
$session_key = $arr['session_key'];
//连接数据库的sql语句
$conn = new mysqli('localhost:3306', '你的数据库账号', '你的数据库密码', 'wx_link');
//连接失败时
if($conn->connect_error){
die("连接失败:" . $conn->connect_error);
}
//正常连接
// 执行数据库连接和查看表中是否存在相同的openid
$result = mysqli_query($conn, "select * from users where openid = '$openid'");
$result = mysqli_fetch_assoc($result);
if($result != null){
$result = json_encode($result);
echo $result;
}else{
$sql = "insert into users(openid, nickName, session_key) values('".$openid."', '".$nickName."', '".$session_key."');";
if($conn->query($sql)){
echo "succeed";
}else{
die('fail');
}
}
?>
添加与修改行程表:
<?php
//根据两个主键openid和dayOfWeek将数据插入指定位置
$openid = $_GET['openid'];
$dayOfWeek = $_GET['dayOfWeek'];
//要插入的数据
$mFir = $_GET['mFir'];
$mSec = $_GET['mSec'];
$aFir = $_GET['aFir'];
$aSec = $_GET['aSec'];
//建立mysql连接,输入mysql的账号和密码以及数据库名称
$conn = new mysqli('localhost:3306', '你的数据库名称', '你的数据库密码', 'wx_link');
//检测连接
if($conn->connect_error){
die("连接失败:" . $conn->connect_error);
}
$sql = "";
$isNull = $conn->query("select * from schedule where user_id = '".$openid."' and dayOfWeek = '".$dayOfWeek."' ");
//表为空
if(mysqli_num_rows($isNull) == 0){
$sql = "insert into schedule(user_id, dayOfWeek, mFir, mSec, aFir, aSec) values('".$openid."', '".$dayOfWeek."', '".$mFir."', '".$mSec."', '".$aFir."', '".$aSec."');";
echo "表为空";
}else{
$sql = "update schedule set mFir = '".$mFir."', mSec = '".$mSec."', aFir = '".$aFir."', aSec = '".$aSec."' where user_id = '".$openid."' and dayOfWeek = '".$dayOfWeek."';";
echo "表不为空";
}
if($conn->query($sql) === TRUE){
echo "succeed";
}else{
echo "Error:" . $conn->error;
}
$conn->close();
?>
查看行程表:
<?php
//从小程序传过来的参数
$openid = $_GET['openid'];
$dayOfWeek = $_GET['dayOfWeek'];
//创建连接
$conn = new mysqli('localhost:3306', 'root', 'aa5153222', 'wx_link');
//连接失败
if($conn->connect_error){
die("连接失败:" . $conn->connect_error);
}
//返回的数组
$res = array('error' => false);
//设置返回数据的格式为utf8
$conn->query("set names utf8");
//sql语句查询表中所有数据
$sql = $conn->query("select mFir, mSec, aFir, aSec from schedule where user_id = '".$openid."' and dayOfWeek = '".$dayOfWeek."' ");
//新建一个数组 接收数据
$daySchedule = array();
//遍历查询的结果
while($row = $sql->fetch_assoc()){
array_push($daySchedule, $row);
}
$res['daySchedule'] = $daySchedule;
// 关闭连接
$conn->close();
header("Content-type:application/json");
// 以json的格式返回查询到的数据
echo json_encode($res);
die();
?>
在添加修改和查看行程中需要连接服务器并操作服务器的mysql数据库实现种种操作
只用两个表就可以实现不同的用户自增加和修改行程这个功能
users表设置主键openid用来存储用户的小程序的openid(微信用户唯一标识)
schedule表用来记录每天四个行程可以理解为课表用dayOfWeek来区分星期一到星期日不同的行程,然后添加从键user_id对应users表的openid