开发微信小程序的过程记录

目录

1.运用阿里巴巴的IconFont

2.小程序需要运用到的路由类型

3.绝对定位下的水平居中实现

4.选择图片和视频

5. 小程序连接数据库

6.存储多个对象的数组

7. 上传图片等文件至服务器

8.服务器中的PHP文件传中文数据至数据库乱码 

9.获取用户的手机号(巨坑)

10.无法访问上传的图片

11.video组件的controls属性无效

12.配置服务器信息中的request合法域名

13.服务器的数据库数据以Json格式接收和回传

14.获取数据库返回的json格式的数据长度

15.从服务器获取的jsonObject需转成数组才能添加额外属性

16.引入图表wxcharts.js 

17.左滑删除

18.写过最长的SQL语句


1.运用阿里巴巴的IconFont

将喜欢的icon收藏起来后添加到相应的项目中,然后下载至本地,得到download.zip压缩文件。

将压缩文件解压,把文件夹中的iconfont.css改名为icon.wxss,然后复制粘贴到小程序项目中

当需要引用某个icon时,可在icon.wxss中或是打开解压得到的文件demo_index.html找到对应的编号(如:照相机icon的编号是e663)

以照相机icon为例,将icon的名称和编号应用到以下的模板中

<!--demo.wxml-->
<icon class="iconfont icon-camera"></icon>

在demo.wxss中import一开始改了名的icon.wxss文件

@import "../../icon.wxss";

.icon-camera{
  font-size: 56rpx;
}

即可显示对应的照相机icon了

 

2.小程序需要运用到的路由类型

 

3.绝对定位下的水平居中实现

.btn{
    position: absolute;
    left: 0;
    right: 0;
    margin: auto;
}

 

4.选择图片和视频

①实现页面的布局

.wxml文件如下:

<text class="titletext textfont">添加图片(最多选4张)</text>
      <view class="addImage">
        <block wx:for="{{imgArr}}" wx:key="key">
          <view class="selected" data-id="{{index}}">
            <image class="itemImage" data-id="{{index}}" src="{{item}}" bindtap="showImage"></image>
            <image class="closeImv" src="../../images/close.png" mode="scaleToFill" catchtap="deleteImage"  data-id="{{index}}"></image>
            <view class="info textfont">
              <view class="subInfo">
                <text>名称</text>
                <input class="nameInput " data-id="{{index}}" maxlength='10'></input>
              </view>
              <view class="subInfo">
                <text>备注</text>
                <textarea class="remarkInput" data-id="{{index}}" maxlength='50'></textarea>
              </view>
            </view>
          </view>
        </block>
        <view class="chooseView" bindtap="chooseImage" wx:if="{{chooseImageShow}}">
          <image class="chooseImv" src="../../images/add.png"></image>
        </view>
      </view>
      <text class="titletext textfont">添加视频(最多选2段)</text>
      <view class="addVideo">
        <block wx:for="{{videoArr}}" wx:key="key">
        <view class="selected"  data-id="{{index}}">
          <video class="itemVideo" data-id="{{index}}" id="{{index}}" src="{{item}}" bindtap="showVideo"></video>
          <image class="closeImv" src="../../images/close.png" mode="scaleToFill" catchtap="deleteVideo" data-id="{{index}}"></image>
          <view class="info textfont">
              <view class="subInfo">
                <text>名称</text>
                <input class="nameInput " data-id="{{index}}" maxlength='10'></input>
              </view>
              <view class="subInfo">
                <text>备注</text>
                <textarea class="remarkInput" data-id="{{index}}" maxlength='50'></textarea>
              </view>
            </view>
        </view>
        </block>
        <view class="chooseView" bindtap="chooseVideo" wx:if="{{chooseVideoShow}}">
          <image class="chooseImv" src="../../images/add.png"></image>
        </view>
      </view>

.wxss文件如下: 

.addImage{
  margin-left: 30rpx;
  padding: 10rpx 0;
  width: 192rpx;
  height: 652rpx;
  background-color: #EEEEEE;
  border: 1rpx dashed gray;
}

.addVideo{
  margin-left: 30rpx;
  padding: 10rpx 0;
  width: 192rpx;
  height: 332rpx;
  background-color: #EEEEEE;
  border: 1rpx dashed gray;
}

.addImage .chooseView, .addVideo .chooseView{
  width: 150rpx;
  height: 150rpx;
  background-color: #ffffff;
  margin: 10rpx 20rpx;
  border: 1px solid lightgray;
  text-align: center;
  line-height: 220rpx;
  border-radius: 5px;
}

.addImage .chooseImv, .addVideo .chooseImv{
  width: 100rpx;
  height: 100rpx;
}

.addImage .selected, .addVideo .selected{
  margin: 10rpx 20rpx;
  width: 150rpx;
  height:150rpx;
  position: relative;
}

.addImage .selected .itemImage, .addVideo .selected .itemVideo{
  width: 100%;
  height: 100%;
}
.addImage .selected .closeImv, .addVideo .selected .closeImv{
  position: absolute;
  right: -15rpx;
  top: -15rpx;
  width: 40rpx;
  height:40rpx;
}

.info{
  width: 500rpx;
  height: 150rpx;
  display: inline-block;
  position: absolute;
  margin-left: 30rpx;
}

.subInfo{
  display: flex;
}

.subInfo text{
  margin: 0 20rpx;
}

.nameInput{
  width: 300rpx;
  height: 40rpx;
  line-height: 40rpx;
  border-bottom: 1rpx solid lightgray;
  padding: 0 20rpx;
  margin-bottom: 10rpx;
}

.remarkInput{
  width: 330rpx;
  height: 80rpx;
  padding: 0 10rpx;
  box-shadow: 0 0 10rpx lightgray inset;
}

②整体.js文件代码

Page({
  data: {
    imgArr: [],
    chooseImageShow: true,
    videoArr: [],
    chooseVideoShow: true,
  },

  chooseImage: function () {
    var that = this;
    wx.chooseImage({
      count: 4 - that.data.imgArr.length,
      success: function (res) {
        if (res.tempFilePaths.count == 0) {
          return;
        }
        var imgArrNow = that.data.imgArr;
        imgArrNow = imgArrNow.concat(res.tempFilePaths);
        that.setData({
          imgArr: imgArrNow
        })
        that.chooseImageShow();
      }
    })
  },

  deleteImage: function (e) {
    var imgArr = this.data.imgArr;
    var itemIndex = e.currentTarget.dataset.id;
    imgArr.splice(itemIndex, 1);
    this.setData({
      imgArr: imgArr
    })
    this.chooseImageShow();
  },

  chooseImageShow: function () {
    if (this.data.imgArr.length >= 4) {
      this.setData({
        chooseImageShow: false
      })
    } else {
      this.setData({
        chooseImageShow: true
      })
    }
  },

  showImage: function (e) {
    var imgArr = this.data.imgArr;
    var itemIndex = e.currentTarget.dataset.id;
    wx.previewImage({
      current: imgArr[itemIndex],
      urls: imgArr
    })
  },

  chooseVideo: function () {
    var that = this;
    wx.chooseVideo({
      count: 2 - that.data.videoArr.length,
      success: function (res) {
        if (res.tempFilePath.count == 0) {
          return;
        }
        var videoArrNow = that.data.videoArr;
        videoArrNow = videoArrNow.concat(res.tempFilePath);
        that.setData({
          videoArr: videoArrNow
        })
        that.chooseVideoShow();
      }
    })
  },

  chooseVideoShow: function () {
    if (this.data.videoArr.length >= 2) {
      this.setData({
        chooseVideoShow: false
      })
    } else {
      this.setData({
        chooseVideoShow: true
      })
    }
  },

  deleteVideo: function (e) {
    var videoArr = this.data.videoArr;
    var itemIndex = e.currentTarget.dataset.id;
    videoArr.splice(itemIndex, 1);
    this.setData({
      videoArr: videoArr
    })
    this.chooseVideoShow();
  },

  showVideo: function (e) {
    var itemIndex = e.currentTarget.dataset.id;
    var videoContext = wx.createVideoContext(itemIndex.toString());
    videoContext.play();
  },
})

 

 

5. 小程序连接数据库

先购买腾讯云服务器和域名,按照教程登录云服务器(本人使用Windows 2012 R2 数据中心版 64位中文版)

再根据腾讯云官方文档 (https://cloud.tencent.com/document/product/213 )进行各种操作,如上传文件、安装配置IIS、安装PHP、安装搭建MySQL等操作。

PHP: Version 7.1.26; MySQL:Version 5.5.64;

在安装PHP时会打印phpinfo(),此时可以留意是否有mysqli,如下:

(若没有且PHP连接MySQL时出现“Call to undefined function mysqli_connect()”的错误时,可点击这里尝试该大神的方法

 

接着在云服务器中下载Navicat for MySQL,把sql文件导入到Navicat

步骤一,打开Navicat,新建数据库,输入数据库名后按确定键

步骤二,右键点击新建数据库,选择 运行SQL文件 后,选择相应的文件后点击开始

小程序中通过wx.request()访问云服务器中的php,而php访问mysql,如下

click: function () {
    wx.request({
      url: 'http://xxxxxxxx/index.php',
      data: {
        username: 'xxx',
        password: 'xxx',
        database: 'xxx',
      },
      success: function (res) {
        console.log(res)
      },
    })
  }

云服务器的index.php 的代码如下 (编写PHP时,可参照官网http://php.net/manual/zh/book.mysqli.php 里面mysqli的API)

<?php
$username = $_GET['username'];
$password = $_GET['password'];
$database = $_GET['database'];

$mysqli = new mysqli("localhost", $username, $password, $database);


if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* return name of current default database */
if ($result = $mysqli->query("SELECT DATABASE()")) {
    $row = $result->fetch_row();
    printf("this database is %s.\n", $row[0]);
    $result->close();
}

$mysqli->close();
?>

 

6.存储多个对象的数组

Page({
  data: {
    imageArr: [], //存储图片的url
    imageInfo: [], //分别存储各个图片的信息
  },

  addImage: function () {
    var imageArr= this.data.imageArr;
    for (var i in imageArr) {
        this.setData({
            ['imageInfo[' + i + '].url']: imageArr[i],
            ['imageInfo[' + i + '].name']: "",
            ['imageInfo[' + i + '].remark']: ""
        })
    }
  },
})

console.log(this.data.imageInfo)打印出来的结果如下:

 

7. 上传图片等文件至服务器

小程序的js文件:

uploadFiles: function () {
    var that = this;
    for (var i = 0; i < that.data.imageArr.length; i++) {
      wx.uploadFile({
        url: 'http://XXXXXXXX/uploadFiles.php',
        filePath: that.data.imageArr[i],
        name: 'file',
        formData: {
          recordID: that.data.recordID,
        },
        success: function (res) {
          console.log(res)
        }
      })
    }
  }

服务器的PHP文件:

<?php
	date_default_timezone_set("Asia/Shanghai");
	$recordID = $_POST['recordID'];
	if(is_uploaded_file($_FILES['file']['tmp_name'])) {  
		$uploaded_file = $_FILES['file']['tmp_name'];  
		$user_path = '/upload/images/'.$recordID;	
		if(!file_exists($user_path)) {  
			if(mkdir($user_path, 0777, true)){
				echo "Create Directory Successfully.";
			} else {
				echo "Fail to Create Directory.";
			}
		} 
		$file_true_name = $_FILES['file']['name']; 
		$move_to_file = $user_path."/".time().rand(1000,9999)."-".date("Y-m-d").substr($file_true_name,strrpos($file_true_name,"."));
		if(move_uploaded_file($uploaded_file,iconv("utf-8","gb2312",$move_to_file))) {  
			echo "Upload File Successfully ".date("Y-m-d H:i:sa"); 
		} else {  
			echo "Fail to Upload File ".date("Y-m-d H:i:sa"); 
		}
	} else {  
		echo "Fail to Upload File ".date("Y-m-d H:i:sa");  
	}  
?>

 

8.服务器中的PHP文件传中文数据至数据库乱码 

$mysqli->query("SET NAMES utf8");

这行代码是正确的,但是我在操作过程中一直试不成功,最后找到了原因,那就是我数据库某些字段的编码是latin,所以要注意字段是否设置了utf-8

 

 

9.获取用户的手机号(巨坑)

首先,获取手机号的使用方法

需要将 <button> 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及 app_id 进行解密获取手机号。

所以当我们得到encryptedData后,要做的就是解密,然而官网给的方法里面埋了个大坑,先说一下官网给的是示例代码,下载后打开对应php语言文件夹得到3个php文件:demo.php 、 errorCode.php 、 wxBizDataCrypt.php

然而我根据示例只改动demo.php的情况下,代码总是报错,最终是一篇“小程序填坑:2018最新getPhoneNumber功能详解” 的文章提到了官网把重要的 pkcs7Encoder.php 给删除了,而恰好这个文档也是解析过程中也是必不可少的,所以我在服务器中添加了该文档,并对 wxBizDataCrypt.php 进行了相应的修改才得以成功获取用户手机号

 

10.无法访问上传的图片

简言之就是上传的时候是把图片先存放在临时文件夹中的,然后再把图片移到指定的文件夹中,虽然指定的文件夹设置了所有的的权限,但是这个临时文件夹的属性权限导致了这个图片的属性权限和指定文件夹的权限不一致,所以无权限访问。

 

 

11.video组件的controls属性无效

当我们把controls属性写成controls="false"时,"false"会被识别为false字符串,自动转化为布尔值是ture,所以需要加上双大括号才可识别布尔值为false,即controls="{{false}}"。

 

 

12.配置服务器信息中的request合法域名

在配置request合法域名为https://api.weixin.qq.com时,我们会发现会出现提示:“为保障帐号安全不可使用此域名地址”。

官方给出的解释是

小程序的开发者密码(AppSecret)是一个非常重要的字段,使用该密码可以调用小程序的所有后台接口。请不要将该字段放置在微信小程序的前端代码中,因为微信手机客户端容易被反编译并轻松获得Appsecret,造成重大的安全威胁。开发者应将Appsecret保存到后台服务器中,通过服务器使用Appsecert获取Accesstoken。

 在编写代码过程中发现了安装的php版本中的php_openssl.dll这个模块没有开启,解决方法只需在php.ini上把“;extension=php_openssl.dll”改成“extension=php_openssl.dll”(即删掉前置的分号)。

 

 

13.服务器的数据库数据以Json格式接收和回传

接收代码:

<?php
	$username = $_GET['username'];
	$password = $_GET['password'];
	$database = $_GET['database'];
	$id = $_GET['id'];
	$profileInfo = $_GET['profileInfo'];
	$array = json_decode($profileInfo, TRUE);
	
	$mysqli = new mysqli("localhost", $username, $password, $database);
	$mysqli->query("SET NAMES utf8");
	if (mysqli_connect_errno()) {
		printf("Connect failed: %s\n", mysqli_connect_error());
		exit();
	}

	$sql = "UPDATE user SET name = '{$array['name']}', email = '{$array['email']}', qqNum = '{$array['qqNum']}', phoneNum = '{$array['phoneNum']}', gender = '{$array['gender']}', career = '{$array['career']}'  WHERE id = '{$id}'";
	if ($result = $mysqli->query($sql)){
		echo 'Update data successfully.'; 
	}else {
		die('Error: ' . mysqli_error());
	}

	$mysqli->close();
?>

 回传代码:

<?php
	header("Content-type:text/html;charset=utf-8");//字符编码设置  
	$username = $_GET['username'];
	$password = $_GET['password'];
	$database = $_GET['database'];
	$id = $_GET['id'];

	$mysqli = new mysqli("localhost", $username, $password, $database);
	$mysqli->query("SET NAMES utf8");
	if (mysqli_connect_errno()) {
		printf("Connect failed: %s\n", mysqli_connect_error());
		exit();
	}

	$sql = "SELECT count(*) FROM user WHERE id = '{$id}'";
	if ($result = $mysqli->query($sql)) {
		$row = $result->fetch_array(MYSQLI_NUM);
		if($row[0] == '0') {
			printf("%s\n", $row[0]);
		}else {
			$sql = "SELECT id, name, email, qqNum, phoneNum, gender, career FROM user WHERE id = '{$id}'";
			if($result = $mysqli->query($sql)){
				$jarr = array();
				$rows = $result->fetch_array(MYSQLI_ASSOC);
				$jobj = new stdclass();
				foreach($rows as $key => $value){
					$jobj -> $key = $value;
				}
				echo json_encode($jobj);
			}
		}
		$result->close();
	}else {
		die('Error: ' . mysqli_error());
	}

	$mysqli->close();
?>

 

 

14.获取数据库返回的json格式的数据长度

  getJsonLength: function(jsonData) {
    var length = 0;
    for (var temp in jsonData) {
      length++;
    }
    return length;
  }

 

 

15.从服务器获取的jsonObject需转成数组才能添加额外属性

  jsonObj2Array: function (jsonObj) {
    var array = [];
    for (var i = 0; i < this.getJsonLength(jsonObj); i++) {
      array[i] = jsonObj[i];
    }
    return array;
  }

假如不转成数组,则添加的属性会直接覆盖原有的jsonObject数据。

 

 

16.引入图表wxcharts.js 

下载地址 https://gitee.com/Q_Augly/wx-charts.git  

有关demo链接: https://blog.csdn.net/m0_37805167/article/details/75160063

 

 

17.左滑删除

参考文章:https://blog.csdn.net/mi_ni123/article/details/80021048

 

 

18.写过最长的SQL语句

 值得一提的是GROUP_CONCAT(distinct ***)的意义:

GROUP_CONCAT是把某个字段合并成一个字符串,distinct的作用是去重。

SELECT 
    event.name, 
    subject.name as subject, 
    GROUP_CONCAT(distinct adultertype.name) as adultertype, 
    GROUP_CONCAT(distinct adulterlink.name) as adulterlink, 
    GROUP_CONCAT(distinct motive.name) as motive, 
    event.description 
FROM (
        (
            (
                (
                    (
                        (
                            event LEFT JOIN subject 
                            ON event.subject = subject.id
                        ) LEFT JOIN event2adultertype 
                        ON event.id = event2adultertype.event
                    )LEFT JOIN adultertype 
                    ON event2adultertype.adultertype = adultertype.id
                ) LEFT JOIN eventadulterlink 
                ON event.id = eventadulterlink.event
            ) LEFT JOIN adulterlink 
            ON eventadulterlink.adulterlink = adulterlink.id
        )LEFT JOIN event2motive 
        ON event.id = event2motive.event
    ) LEFT JOIN motive 
    ON event2motive.motive = motive.id 
WHERE event.id = '4' 
GROUP BY event.id;

 

 

参考资料

使用微信小程序对服务器上MySQL数据库进行操作 

https://blog.csdn.net/weixin_43566648/article/details/85543230

PHP中出现Call to undefined function mysqli_connect() 

https://blog.csdn.net/www121104115/article/details/75006164

微信小程序用setData修改数组或对象中的一个属性值

http://www.cnblogs.com/Mrrabbit/p/7680934.html

小程序的图片上传wx.uploadFile及后台PHP接收文件并存储到服务器

https://blog.csdn.net/csl125/article/details/79205143

小程序填坑:2018最新getPhoneNumber功能详解 

https://blog.csdn.net/qq_38194393/article/details/81382108

解决PHP在Windows IIS 上传的图片无法访问的问题  

https://www.cnblogs.com/huangtailang/p/4608175.html

PHP中把数据库查询结果输出为json格式 

https://www.cnblogs.com/yiven/p/6491019.html

小程序wx-charts的项目实用

https://blog.csdn.net/m0_37938910/article/details/80744562

【微信小程序】滑动删除效果最全Demo 

https://blog.csdn.net/mi_ni123/article/details/80021048

 

站在巨人的肩膀上,持续更新中!

开发微信小程序的打卡记录功能可以按照以下步骤进行: 1. 首先,你需要设计小程序的用户登录授权规范。根据微信官方的要求,用户在未授权之前应该能够大概了解小程序的功能。因此,在用户进入小程序时,你可以展示一些功能的预览,但在使用这些功能之前,需要用户进行授权。这样可以避免审核不通过的问题。\[2\] 2. 接下来,你需要设计打卡记录的界面和功能。用户可以在小程序中进行打卡操作,并记录相关的信息,如打卡时间、地点等。你可以使用小程序提供的数据存储功能,将打卡记录保存在后台服务器或云数据库中。 3. 如果你的打卡记录功能涉及到上传图片,你可以使用循环上传的方法来实现批量上传图片。在选择图片时,将图片存储在一个数组中,然后循环这个数组,使用小程序提供的上传文件接口将图片上传到服务器。\[3\] 4. 在上传图片时,你可以考虑使用微信官方提供的图片内容安全检测接口,对上传的图片进行法规检验,以防止包含违规、涉黄等信息。这样可以增加审核通过的几率。\[1\] 5. 最后,完成开发后,你需要将小程序的代码上传并提交给微信官方进行审核。等待审核通过后,你的小程序就可以正式上线,用户可以使用打卡记录功能了。 总结起来,开发微信小程序的打卡记录功能需要设计用户登录授权规范,实现打卡记录的界面和功能,处理批量上传图片的难点,并在上传图片时进行内容安全检测。完成开发后,将代码上传并提交审核,等待审核通过后即可上线使用。 #### 引用[.reference_title] - *1* *2* *3* [微信小程之打卡小程序开发](https://blog.csdn.net/zyf_smile/article/details/106671111)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值