• 微信小程序开发之后台数据交互及wxs应用


    目录

    一、后端准备

    1. 应用配置 

    2. 数据源配置

    二、数据库

    1. 创建

    2. 数据表

    3. 数据测试 

    三、前端

    1. 请求方法整合

    2. 数据请求

    3. WXS的使用

    4. 样式美化

    5. 页面


    一、后端准备

    通过SpringMVCmybatis的技术学习,还有前后端分离的技术应用,在我博客中也信息的学习及技术,通过这些来完成后端的代码及功能的实现,相信各位大佬都可以编写开发出来。

    而我这里只告诉大家在后端的配置,整合及应用

    1. 应用配置 

    实现导入的引用,在项目的 pom.xml 中进行引用配置

    我的引用配置如下 : 

    pom.xml

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <parent>
    6. <groupId>org.springframework.bootgroupId>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <version>2.6.2version>
    9. <relativePath/>
    10. parent>
    11. <groupId>com.CloudJungroupId>
    12. <artifactId>minoaartifactId>
    13. <version>0.0.1-SNAPSHOTversion>
    14. <name>minoaname>
    15. <description>Demo project for Spring Bootdescription>
    16. <properties>
    17. <java.version>1.8java.version>
    18. <fastjson.version>1.2.70fastjson.version>
    19. <jackson.version>2.9.8jackson.version>
    20. properties>
    21. <dependencies>
    22. <dependency>
    23. <groupId>org.springframework.bootgroupId>
    24. <artifactId>spring-boot-starter-jdbcartifactId>
    25. dependency>
    26. <dependency>
    27. <groupId>org.springframework.bootgroupId>
    28. <artifactId>spring-boot-starter-webartifactId>
    29. dependency>
    30. <dependency>
    31. <groupId>org.mybatis.spring.bootgroupId>
    32. <artifactId>mybatis-spring-boot-starterartifactId>
    33. <version>2.2.1version>
    34. dependency>
    35. <dependency>
    36. <groupId>mysqlgroupId>
    37. <artifactId>mysql-connector-javaartifactId>
    38. <version>5.1.44version>
    39. <scope>runtimescope>
    40. dependency>
    41. <dependency>
    42. <groupId>org.projectlombokgroupId>
    43. <artifactId>lombokartifactId>
    44. <optional>trueoptional>
    45. dependency>
    46. <dependency>
    47. <groupId>com.alibabagroupId>
    48. <artifactId>fastjsonartifactId>
    49. <version>${fastjson.version}version>
    50. dependency>
    51. dependencies>
    52. <build>
    53. <plugins>
    54. <plugin>
    55. <groupId>org.springframework.bootgroupId>
    56. <artifactId>spring-boot-maven-pluginartifactId>
    57. <configuration>
    58. <excludes>
    59. <exclude>
    60. <groupId>org.projectlombokgroupId>
    61. <artifactId>lombokartifactId>
    62. exclude>
    63. excludes>
    64. configuration>
    65. plugin>
    66. <plugin>
    67. <groupId>org.mybatis.generatorgroupId>
    68. <artifactId>mybatis-generator-maven-pluginartifactId>
    69. <version>1.3.2version>
    70. <dependencies>
    71. <dependency>
    72. <groupId>mysqlgroupId>
    73. <artifactId>mysql-connector-javaartifactId>
    74. <version>${mysql.version}version>
    75. dependency>
    76. dependencies>
    77. <configuration>
    78. <overwrite>trueoverwrite>
    79. configuration>
    80. plugin>
    81. plugins>
    82. build>
    83. project>

    当然,可以根据自己有更多需求进行应用配置的增加。

    2. 数据源配置

    在后端项目中进行数据库的路径进行配置

    在我的项目这里是在appliation.yml文件中进行数据源的配置,各位大佬有很好的方法也可。

    appliation.yml

    1. spring:
    2. datasource:
    3. #type连接池类型 DBCP,C3P0,Hikari,Druid,默认为Hikari
    4. type: com.zaxxer.hikari.HikariDataSource
    5. driver-class-name: com.mysql.jdbc.Driver
    6. url: jdbc:mysql://localhost:3306/mybatis_oapro?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    7. username: root
    8. password: 123456
    9. mybatis:
    10. mapper-locations: classpath*:mapper/*.xml #指定mapper文件位置
    11. type-aliases-package: com.CloudJun.minoa.model #指定自动生成别名所在包
    12. logging:
    13. level:
    14. root: info
    15. com.CloudJun.minoa.mapper: debug

    还有生成mapper接口,model实体类,mapper映射文件已是很轻松的操作。

    二、数据库

    1. 创建

    根据后端的数据源的配置进行创建数据库

    数据库的创建只需要根据以下图中输入填写即可:

    2. 数据表

    在后台需要准备一些数据表,并且提供一定的数据。

    以下是我创建的数据表,可以依据进行参考来创建

    t_oa_data_dict

    结构:

    t_oa_data_item

    结构:

    t_oa_meeting_feedback

    结构:

    t_oa_meeting_info

    结构:

    t_oa_meeting_option

    结构:

    t_oa_meeting_room

    结构:

    t_oa_meeting_vote

    结构:

    t_oa_permission

    结构:

    t_oa_role

    结构:

    t_oa_role_permission

    结构:

    t_oa_user

    结构:

    wx_user

    结构:

    以上的数据表的设计呢,相对来是比较简洁具体,没有太多的很多设计。

    并且需要在以上的表格中增加一些数据,进行之后前端的显示。

    3. 数据测试 

    在以上完成之后呢,确保配置及应用的完成,在后端开启服务,并且在浏览器中进行输入后端的数据请求地址,是否可以在后端查询到数据库中数据。

    请求地址是根据自己的配置来进行输入服务的,如果可以在浏览器中进行数据的查看,说明已经完成,后端及数据库的配置及编写。

    如图所示 : 

    三、前端

    在微信小程序开发中,后台数据交互是非常重要的一部分。通过后台数据交互,可以实现小程序与服务器之间的数据传输和交互。

    一般情况下,后台数据交互可以通过以下几种方式实现:

    1. 使用微信提供的wx.request()方法进行网络请求。通过该方法,可以向服务器发送请求并获取返回的数据。可以使用GET、POST等不同的请求方式,传递参数并处理返回的数据。

    2. 使用微信提供的wx.uploadFile()方法进行文件上传。该方法可以将本地文件上传到服务器,并获取服务器返回的数据。

    3. 使用WebSocket进行实时数据传输。WebSocket是一种在单个TCP连接上进行全双工通信的协议,可以实现实时的数据传输。

    在后台数据交互的过程中,可以使用wxs(WeixinScript)进行数据处理和逻辑控制。wxs是一种类似于JavaScript的脚本语言,它可以在.wxml文件中嵌入,并通过数据绑定和事件绑定实现动态效果。

    前端的小程序代码呢,是基于我博客中的代码进行完善 :

    微信小程序开发的OA会议之会议,投票,个人中心的页面搭建及模板,还有自定义组件的学习icon-default.png?t=N7T8https://blog.csdn.net/SAME_LOVE/article/details/133926100?spm=1001.2014.3001.5501

    1. 请求方法整合

    在前端的项目的 utils/util.js 中,封装小程序端的的 request 请求方法,让代码减少重复性

    util.js

    1. const formatTime = date => {
    2. const year = date.getFullYear()
    3. const month = date.getMonth() + 1
    4. const day = date.getDate()
    5. const hour = date.getHours()
    6. const minute = date.getMinutes()
    7. const second = date.getSeconds()
    8. return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
    9. }
    10. const formatNumber = n => {
    11. n = n.toString()
    12. return n[1] ? n : `0${n}`
    13. }
    14. /**
    15. * 封装微信的request请求
    16. */
    17. function request(url, data = {}, method = "GET") {
    18. return new Promise(function (resolve, reject) {
    19. wx.request({
    20. url: url,
    21. data: data,
    22. method: method,
    23. header: {
    24. 'Content-Type': 'application/json',
    25. },
    26. success: function (res) {
    27. if (res.statusCode == 200) {
    28. resolve(res.data);//会把进行中改变成已成功
    29. } else {
    30. reject(res.errMsg);//会把进行中改变成已失败
    31. }
    32. },
    33. fail: function (err) {
    34. reject(err)
    35. }
    36. })
    37. });
    38. }
    39. module.exports = {
    40. formatTime,
    41. request
    42. }

    2. 数据请求

    完善前端项目中的首页 页面的 index.js ,进行数据访问后端,并且显示。

    1. // index.js
    2. // 获取应用实例
    3. const app = getApp()
    4. const api = require("../../config/app")
    5. //应用请求的sj文件
    6. const util = require("../../utils/util")
    7. Page({
    8. //初始化数据
    9. data: {
    10. "images":[
    11. {
    12. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner1.png",
    13. "text": "1"
    14. },
    15. {
    16. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner2.png",
    17. "text": "2"
    18. },
    19. {
    20. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner3.png",
    21. "text": "3"
    22. },
    23. {
    24. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner4.png",
    25. "text": "4"
    26. },
    27. {
    28. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner5.png",
    29. "text": "5"
    30. },
    31. {
    32. "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner6.png",
    33. "text": "6"
    34. }
    35. ]
    36. },
    37. // 事件处理函数
    38. // 获取轮播图的方法
    39. // loadSwiperImgs(){
    40. // let that=this;
    41. // wx.request({
    42. // url: api.SwiperImgs,
    43. // dataType: 'json',
    44. // success(res) {
    45. // // console.log(res)
    46. // that.setData({
    47. // imgSrcs:this.images
    48. // })
    49. // }
    50. // })
    51. // },
    52. // 获取首页会议信息的方法
    53. loadMeetingInfos(){
    54. let that=this;
    55. // wx.request({
    56. // url: api.IndexUrl,
    57. // dataType: 'json',
    58. // success(res) {
    59. // console.log(res)
    60. // that.setData({
    61. // lists:res.data.data.infoList
    62. // })
    63. // }
    64. // })
    65. util.request(api.IndexUrl).then(res=>{
    66. console.log(res)
    67. this.setData({
    68. lists:res.data.infoList
    69. })
    70. }).catch(res=>{
    71. console.log('服器没有开启,使用模拟数据!')
    72. })
    73. },
    74. onLoad() {
    75. if (wx.getUserProfile) {
    76. this.setData({
    77. canIUseGetUserProfile: true
    78. })
    79. }
    80. // this.loadSwiperImgs();
    81. this.loadMeetingInfos();
    82. },
    83. getUserProfile(e) {
    84. // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    85. wx.getUserProfile({
    86. desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
    87. success: (res) => {
    88. // console.log(res)
    89. this.setData({
    90. userInfo: res.userInfo,
    91. hasUserInfo: true
    92. })
    93. }
    94. })
    95. },
    96. getUserInfo(e) {
    97. // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
    98. // console.log(e)
    99. this.setData({
    100. userInfo: e.detail.userInfo,
    101. hasUserInfo: true
    102. })
    103. }
    104. })

    3. WXS的使用

    WXS 代码可以编写在 wxml 文件中的  标签内,或以 .wxs 为后缀名的文件内。

    在wxs中,可以使用一些内置的方法和对象来实现数据处理,如Math、Date等。同时,也可以使用一些自定义的函数和变量来实现特定的业务逻辑。

    通过后台数据交互和wxs应用,可以实现小程序的数据展示、数据操作和业务逻辑的实现。同时,也可以提高小程序的性能和用户体验。

    模块

    每一个 .wxs 文件和  标签都是一个单独的模块。

    每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。

    一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。

    属性名类型默认值说明
    moduleString当前  标签的模块名。必填字段。
    srcString引用 .wxs 文件的相对路径。仅当本标签为单闭合标签标签的内容为空时有效

    module 属性 

    module 属性是当前  标签的模块名。在单个 wxml 文件内,建议其值唯一。有重复模块名则按照先后顺序覆盖(后者覆盖前者)。不同文件之间的 wxs 模块名不会相互覆盖。

    module 属性值的命名必须符合下面两个规则:

    • 首字符必须是:字母(a-zA-Z),下划线(_)
    • 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)

    根据微信小程序的官网,在微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。

    比如我们在项目中的utils文件中创建 .wxs 文件,名为: tools.wxs

    1. function getState(state){
    2. // 状态:0取消会议1待审核2驳回3待开4进行中5开启投票6结束会议,默认值为1
    3. if(state == 0 ){
    4. return '取消会议';
    5. }else if(state == 1 ){
    6. return '待审核';
    7. }else if(state == 2 ){
    8. return '驳回';
    9. }else if(state == 3 ){
    10. return '待开';
    11. }else if(state == 4 ){
    12. return '进行中';
    13. }else if(state == 5 ){
    14. return '开启投票';
    15. }else if(state == 6 ){
    16. return '结束会议';
    17. }
    18. return '其它';
    19. }
    20. var getNumber = function(canyuze,liexize,zhuchiren) {
    21. var s = canyuze+','+liexize+','+zhuchiren;
    22. var array = s.split(',');
    23. var len = array.length;
    24. return len;
    25. }
    26. function formatDate(ts, option) {
    27. var date = getDate(ts)
    28. var year = date.getFullYear()
    29. var month = date.getMonth() + 1
    30. var day = date.getDate()
    31. var week = date.getDay()
    32. var hour = date.getHours()
    33. var minute = date.getMinutes()
    34. var second = date.getSeconds()
    35. //获取 年月日
    36. if (option == 'YY-MM-DD') return [year, month, day].map(formatNumber).join('-')
    37. //获取 年月
    38. if (option == 'YY-MM') return [year, month].map(formatNumber).join('-')
    39. //获取 年
    40. if (option == 'YY') return [year].map(formatNumber).toString()
    41. //获取 月
    42. if (option == 'MM') return [mont].map(formatNumber).toString()
    43. //获取 日
    44. if (option == 'DD') return [day].map(formatNumber).toString()
    45. //获取 年月日 周一 至 周日
    46. if (option == 'YY-MM-DD Week') return [year, month, day].map(formatNumber).join('-') + ' ' + getWeek(week)
    47. //获取 月日 周一 至 周日
    48. if (option == 'MM-DD Week') return [month, day].map(formatNumber).join('-') + ' ' + getWeek(week)
    49. //获取 周一 至 周日
    50. if (option == 'Week') return getWeek(week)
    51. //获取 时分秒
    52. if (option == 'hh-mm-ss') return [hour, minute, second].map(formatNumber).join(':')
    53. //获取 时分
    54. if (option == 'hh-mm') return [hour, minute].map(formatNumber).join(':')
    55. //获取 分秒
    56. if (option == 'mm-dd') return [minute, second].map(formatNumber).join(':')
    57. //获取 时
    58. if (option == 'hh') return [hour].map(formatNumber).toString()
    59. //获取 分
    60. if (option == 'mm') return [minute].map(formatNumber).toString()
    61. //获取 秒
    62. if (option == 'ss') return [second].map(formatNumber).toString()
    63. //默认 时分秒 年月日
    64. return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
    65. }
    66. function formatNumber(n) {
    67. n = n.toString()
    68. return n[1] ? n : '0' + n
    69. }
    70. function getWeek(n) {
    71. switch(n) {
    72. case 1:
    73. return '星期一'
    74. case 2:
    75. return '星期二'
    76. case 3:
    77. return '星期三'
    78. case 4:
    79. return '星期四'
    80. case 5:
    81. return '星期五'
    82. case 6:
    83. return '星期六'
    84. case 7:
    85. return '星期日'
    86. }
    87. }
    88. module.exports = {
    89. getState: getState,
    90. getNumber: getNumber,
    91. formatDate:formatDate
    92. };

    该文件是完善效果会议信息中的,人员数量,及时间的一个完善,更美化的显示。

    4. 样式美化

    在 index.wxss 中进一步的效果美化。

    1. /**index.wxss**/
    2. .swiper-item {
    3. height: 300rpx;
    4. width: 100%;
    5. border-radius: 10rpx;
    6. }
    7. .mobi-title {
    8. font-size: 12pt;
    9. color: #777;
    10. line-height: 110%;
    11. font-weight: bold;
    12. width: 100%;
    13. padding: 15rpx;
    14. background-color: #f3f3f3;
    15. }
    16. .mobi-icon {
    17. padding: 0rpx 3rpx;
    18. border-radius: 3rpx;
    19. background-color: #ff7777;
    20. position: relative;
    21. margin-right: 10rpx;
    22. }
    23. /*list*/
    24. .list {
    25. display: flex;
    26. flex-direction: row;
    27. width: 100%;
    28. padding: 0 20rpx 0 0;
    29. border-top: 1px solid #eeeeee;
    30. background-color: #fff;
    31. margin-bottom: 5rpx;
    32. /* border-radius: 20rpx;
    33. box-shadow: 0px 0px 10px 6px rgba(0,0,0,0.1); */
    34. }
    35. .list-img {
    36. display: flex;
    37. margin: 10rpx 10rpx;
    38. width: 150rpx;
    39. height: 220rpx;
    40. justify-content: center;
    41. align-items: center;
    42. }
    43. .list-img .video-img {
    44. border-radius: 4px;
    45. width: 130rpx;
    46. height: 140rpx;
    47. }
    48. .list-detail {
    49. margin: 10rpx 10rpx;
    50. display: flex;
    51. flex-direction: column;
    52. width: 600rpx;
    53. height: 220rpx;
    54. }
    55. .list-title text {
    56. font-size: 11pt;
    57. color: #333;
    58. font-weight: bold;
    59. }
    60. .list-detail .list-tag {
    61. display: flex;
    62. height: 70rpx;
    63. }
    64. .list-tag .state {
    65. font-size: 9pt;
    66. color: #81aaf7;
    67. width: 120rpx;
    68. border: 1px solid #93b9ff;
    69. border-radius: 2px;
    70. margin: 10rpx 0rpx;
    71. display: flex;
    72. justify-content: center;
    73. align-items: center;
    74. }
    75. .list-tag .join {
    76. font-size: 11pt;
    77. color: #bbb;
    78. margin-left: 20rpx;
    79. display: flex;
    80. justify-content: center;
    81. align-items: center;
    82. }
    83. .list-tag .list-num {
    84. font-size: 11pt;
    85. color: #ff6666;
    86. }
    87. .list-info {
    88. font-size: 9pt;
    89. color: #bbb;
    90. margin-top: 20rpx;
    91. }
    92. .bottom-line{
    93. display: flex;
    94. height: 60rpx;
    95. justify-content: center;
    96. align-items: center;
    97. background-color: #f3f3f3;
    98. }
    99. .bottom-line text{
    100. font-size: 9pt;
    101. color: #666;
    102. }

    5. 页面

    再修改首页页面中的 index.wxml  文件

    1. <view>
    2. <swiper autoplay="true" indicator-dots="true" indicator-color="#fff" indicator-active-color="#00f">
    3. <block wx:for="{{images}}" wx:key="text">
    4. <swiper-item>
    5. <view>
    6. <image src="{{item.img}}" class="swiper-item" />
    7. view>
    8. swiper-item>
    9. block>
    10. swiper>
    11. view>
    12. <view class="mobi-title">
    13. <text class="mobi-icon">text>
    14. <text>会议信息text>
    15. view>
    16. <wxs src="../../utils/tools.wxs" module="tools" />
    17. <block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id">
    18. <view class="list" data-id="{{item.id}}">
    19. <view class="list-img">
    20. <image class="video-img" mode="scaleToFill" src="{{item.remark}}">image>
    21. view>
    22. <view class="list-detail">
    23. <view class="list-title"><text>{{item.title}}text>view>
    24. <view class="list-tag">
    25. <view class="state">{{tools.getState(item.state)}}view>
    26. <view class="join"><text class="list-num">{{tools.getNumber(item.canyuze,item.liexize,item.zhuchiren)}} text>人报名view>
    27. view>
    28. <view class="list-info"><text>{{item.location}}text> | <text>{{tools.formatDate(item.starttime)}}text>view>
    29. view>
    30. view>
    31. block>
    32. <view class="section bottom-line">
    33. <text>到底啦text>
    34. view>

    后台的服务开起后,可以在模拟器中可以看到的效果 : 

  • 相关阅读:
    等保评测是什么意思
    技术面①Java多线程的四种实现方法并详细举例介绍
    医疗健康产品展:联影医疗
    阈值回归模型(Threshold Regression Model)及R实现
    Abp 项目报错 Microsoft.Data.SqlClient.SqlException (0x80131904)
    中国香港学生IB高分是如何做到的?
    汽车技术市场动态分析
    leetcode 557. Reverse Words in a String III(字符串中单词逆序III)
    Maven引入Aspose依赖
    打包和部署Java应用程序:Maven和Shell脚本的实用方法
  • 原文地址:https://blog.csdn.net/SAME_LOVE/article/details/133953859