【微信小程序】发布投票与用户投票完整讲解

news/2024/7/20 1:18:39 标签: java, 微信小程序, 小程序

目录

前言

       组件功能示例

一、数据库

二、后端接口定义

三、前端准备

3.1 定义连接接口

3.2 Vant Weapp UI 组件库

3.3 授权登录与相关工具

四、小程序编写

4.1 投票组件

WXML

WXSS

JSON

WXJS

效果展示讲解:

4.2  发布投票组件

WXML

WXSS

JSON

WXJS

效果展示讲解:


前言

        本次主要讲解的是在会议系统中完整投票功能,首先建立思维流程:

  1. 先必须要有会议数据,而会议要由发布、审核、待开等,到开启会议后才能进行发布投票功能。
  2. 发布的投票必须要用户进行登录才可投票
  3. 而用户能够查询所有投票以及已投票或结束的投票

总结非常简单,如果要我们去实现,这时候就有许多问题:

  • 需要编写复杂的sql和查询
  • 需要多样化的组件并实现数据交互
  • 需要分析流程与执行顺序

        如果这些都需要自己独立完成,很多东西还要自己去研究测试,不仅要走许多弯路还得花很多时间和心思。嗯...我就是这样过来的,这篇也是爆肝凌晨几点完成的。话不多说,现在就开始进入正题。

组件功能示例

一、数据库

投票功能是建立在会议和用户之上的,所以先介绍一下这两个表:

t_oa_meeting_info:

wx.user: 

主要关注会议状态(state字段)

 

1、存储发布的投票表:

2. 用户投票信息表:

sql预览:

#查询进行中的投票
select * from t_oa_meeting_option where meetingId = (select id from t_oa_meeting_info where state = 5)

#查询结束会议的投票
select * from t_oa_meeting_option where meetingId = (select id from t_oa_meeting_info where state = 6)

#查询票数
select count(*) from t_oa_meeting_vote where optionId = 2

#查询已投的的票
select * from t_oa_meeting_option where id = (select optionId from t_oa_meeting_vote where personId = 5)

 

二、后端接口定义

方法功能:注释 

WxInfoController :会议数据

java">package com.ycxw.ssm.wxcontroller;

import com.ycxw.ssm.mapper.InfoMapper;
import com.ycxw.ssm.model.Info;
import com.ycxw.ssm.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 云村小威
 * @create 2023-10-26 22:28
 */
@RestController
@RequestMapping("/wx/info")
public class WxInfoController {
    @Autowired
    private InfoMapper infoMapper;
    @RequestMapping("/list")
    public Object list (Info info){
        List<Info> list = infoMapper.list(info);
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("infoList",list);
        return ResponseUtil.ok(data);
    }

    //查询所有进行中的会议
    @RequestMapping("/listState")
    public Object listState (Info info){
        info.setState(4);
        List<Info> list = infoMapper.list(info);
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("listState",list);
        return ResponseUtil.ok(data);
    }

    //修改会议状态
    @RequestMapping("/state")
    public Object updateState (Info info){
        infoMapper.updateByPrimaryKeySelective(info);
        return ResponseUtil.ok();
    }
}

 

WXOptionController:投票数据

java">package com.ycxw.ssm.wxcontroller;

import com.ycxw.ssm.mapper.OptionMapper;
import com.ycxw.ssm.model.Option;
import com.ycxw.ssm.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 云村小威
 * @create 2023-10-26 22:28
 */
@RestController
@RequestMapping("/wx/option")
public class WXOptionController {
    @Autowired
    private OptionMapper optionMapper; //正在投票信息

    //查询所有投票
    @RequestMapping("/list")
    public Object list() {
        List<Option> list = optionMapper.list();
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("voteList", list);
        return ResponseUtil.ok(data);
    }

    /*发布投票*/
    @RequestMapping("/add")
    public Object save(Option option) {
        //发起投票
        optionMapper.insertSelective(option);
        return ResponseUtil.ok();
    }

    //查询所有结束的投票
    @RequestMapping("/over")
    public Object selectOverVote() {
        List<Option> list = optionMapper.selectOverVote();
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("overList", list);
        return ResponseUtil.ok(data);
    }

    //查询所有已投票的信息
    @RequestMapping("/already")
    public Object selectByAlready(Long personId) {
        List<Option> list = optionMapper.selectByAlready(personId);
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("alreadyList", list);
        return ResponseUtil.ok(data);
    }

    //模糊查询投票信息
    @RequestMapping("/search")
    public Object SearchVote(Option option) {
        List<Option> list = optionMapper.SearchVote(option);
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("searchList", list);
        return ResponseUtil.ok(data);
    }
}

WXVoteController:用户投票数据

java">package com.ycxw.ssm.wxcontroller;

import com.ycxw.ssm.mapper.VoteMapper;
import com.ycxw.ssm.model.Vote;
import com.ycxw.ssm.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 云村小威
 * @create 2023-10-26 22:28
 */
@RestController
@RequestMapping("/wx/vote")
public class WXVoteController {
    @Autowired
    private VoteMapper voteMapper;

    //查询选项正在投票的会议的票数
    @RequestMapping("/ticket")
    public Object selectByOptionId(Long optionId) {
        Long i = voteMapper.selectByOptionId(optionId);
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("ticket", i);
        return ResponseUtil.ok(data);
    }

    //投票
    @RequestMapping("/add")
    public Object insertSelective(Vote record) {
        int i = voteMapper.insertSelective(record);
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("ok", i);
        return ResponseUtil.ok(data);
    }

}

 

三、前端准备

3.1 定义连接接口

这里只列出本次需要实现功能的接口 

java">// 以下是业务服务器API地址
// 本机开发API地址
var WxApiRoot = 'http://localhost:8080/oapro/wx/';

module.exports = {
  AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登录
  AuthLogout: WxApiRoot + 'auth/logout', //账号登出
  MettingInfoState: WxApiRoot + 'info/listState', //所有进行中的会议
  VoteInfos: WxApiRoot + 'option/list', //所有发布投票的会议
  SearchVote: WxApiRoot + 'option/search', //搜索投票信息
  UpdateState: WxApiRoot + 'info/state', //修改会议状态
  MeetingAddVote: WxApiRoot + 'option/add', //发布投票
  OverVote: WxApiRoot + 'option/over',//所有结束的会议
  AlreadyVote: WxApiRoot + 'option/already',//所有已投的会议
  SelectTicket: WxApiRoot + 'vote/ticket',//查询票数
  AddTicket: WxApiRoot + 'vote/add',//投票
};

3.2 Vant Weapp UI 组件库

本次主要使用 Vant Weapp UI 组件搭建的,学习这个很简单,根据文档安装操作即可:进入 Vant Weapp UI 文档

3.3 授权登录与相关工具

进入 【小程序>微信小程序】授权登录流程解析

主要为了了解微信授权登录的流程和原理,方便更好理解后面的知识。

四、小程序编写

4.1 投票组件

WXML

        这里是利用 vant weapp 组件布局的,里面包括搜索框、tab列表、弹窗、以及一个定位的图片按钮,用于进入发布投票页面。 

<!--pages/vote/list/list.wxml-->
<view style="height: 15rpx;"></view>
<!-- 搜索框 -->
<van-search value="{{ search }}" placeholder="请输入搜索关键词" show-action bind:change="Search" bind:search="onSearch" bind:cancel="onCancel" />
<view style="height: 20rpx;"></view>
<!-- tabs列表 -->
<van-tabs type="card" color="#1989fa">
  <!-- VoteALL -->
  <van-tab title="进行中">
    <van-divider dashed contentPosition="center" customStyle="color: #1989fa; border-color: #1989fa;">
      投一票
    </van-divider>
    <view class="oaFlex">
      <block wx:for-items="{{VoteAll}}" wx:for-item="item" wx:key="item.id">
        <view class="list" data-id="{{item.id}}" bindtap="open_vote" data-text="{{item.title}}">
          <view class="list-detail">
            <view class="list-title"><text>{{item.title}}</text></view>
            <!-- <view class="list-tag">
              <view class="join al-center"><text class="list-num">0</text> 人已投</view>
            </view> -->
          </view>
          <view class="list-img al-center">
            <image class="video-img" mode="scaleToFill" src="{{item.picture}}"></image>
          </view>
        </view>
      </block>
    </view>
  </van-tab>
  <!-- publishVote  -->
  <van-tab title="已结束">
    <view style="height: 50rpx;"></view>
    <view class="oaFlex">
      <block wx:for-items="{{OverVote}}" wx:for-item="item" wx:key="item.id">
        <view class="list" data-id="{{item.id}}" bindtap="open_vote" data-text="{{item.title}}">
          <view class="list-detail">
            <view class="list-title"><text>{{item.title}}</text></view>
            <!-- <view class="list-tag">
              <view class="join al-center"><text class="list-num">0</text> 人已投</view>
            </view> -->
          </view>
          <view class="list-img al-center">
            <image class="video-img" mode="scaleToFill" src="{{item.picture}}"></image>
          </view>
        </view>
      </block>
    </view>
  </van-tab>
  <!-- AlreadyVote  -->
  <van-tab title="已投票">
    <view style="height: 50rpx;"></view>
    <view class="oaFlex">
      <block wx:for-items="{{AlreadyVote}}" wx:for-item="item" wx:key="item.id">
        <view class="list" data-id="{{item.id}}" bindtap="open_vote" data-text="{{item.title}}">
          <view class="list-detail">
            <view class="list-title"><text>{{item.title}}</text></view>
            <!-- <view class="list-tag">
              <view class="join al-center"><text class="list-num">0</text> 人已投</view>
            </view> -->
          </view>
          <view class="list-img al-center">
            <image class="video-img" mode="scaleToFill" src="{{item.picture}}"></image>
          </view>
        </view>
      </block>
    </view>
  </van-tab>
</van-tabs>
<!-- 投票弹出框 -->
<van-dialog use-slot title="投一票" show="{{ showVote }}" show-cancel-button confirm-button-open-type="getUserInfo" bind:close="onClose" bind:getuserinfo="getUserInfo">
  <view style="height: 25rpx;"></view>
  <van-notice-bar scrollable="{{true}}" color="#1989fa" background="#ecf9ff" left-icon="volume-o" text="{{text}}" />
  <view style="height: 15rpx;"></view>
  <van-cell-group inset>
    <van-cell title="当前票数">
      <van-stepper disable-input="{{true}}" value="{{ ticket }}" bind:change="onChange" max="{{ticket+1}}" min="{{ticket}}" />
    </van-cell>
  </van-cell-group>
</van-dialog>
<!-- 发布投票图片按钮 -->
<view style="position:fixed; bottom:10px;width: 150rpx;right: 10px;">
  <van-image bindtap="open_publishVote" round width="5rem" height="5rem" src="/static/images/add.png" />
</view>

WXSS

/* pages/vote/list/list.wxss */
.oaFlex {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.list {
  width: 360px;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: rgb(228, 240, 253);
  border-bottom: 2px solid #d9dbe2;
  margin-bottom: 25px;
}

.video-img {
  width: 360px;
  height: 160px;
}

.list-detail {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.list-title {
  margin-top: 10px;
  height: 30px;
  font-size: 13pt;
  color: #333;
  font-weight: bold;
}

.list-info {
  color: #aaa;
}

.list-num {
  color: red;
  /* font-weight: 700; */
}

.join {
  padding: 0px 0px 0px 10px;
  color: #aaa;
}

.state {
  margin: 0px 6px 0px 6px;
  border: 1px solid #4083ff;
  color: #4083ff;
  padding: 3px 5px 3px 5px;
}

.list-tag {
  padding: 10px 0px 10px 0px;
  display: flex;
  align-items: center;
}

JSON

javascript">{
  "navigationBarTitleText": "投票",
  "usingComponents": {
    "van-row": "@vant/weapp/row/index",
    "van-col": "@vant/weapp/col/index",
    "van-search": "@vant/weapp/search/index",
    "van-switch": "@vant/weapp/switch/index",
    "van-dialog": "@vant/weapp/dialog/index",
    "van-tab": "@vant/weapp/tab/index",
    "van-tabs": "@vant/weapp/tabs/index",
    "van-divider": "@vant/weapp/divider/index",
    "van-image": "@vant/weapp/image/index",
    "van-stepper": "@vant/weapp/stepper/index",
    "van-cell": "@vant/weapp/cell/index",
    "van-cell-group": "@vant/weapp/cell-group/index",
    "van-notice-bar": "@vant/weapp/notice-bar/index"
  }
}

WXJS

javascript">// pages/vote/list.js
var app = getApp();
const api = require('../../../config/api');
const util = require('../../../utils/util.js');

Page({
  /**
   * 页面的初始数据
   */
  data: {
    VoteAll: [], //进行中的投票
    OverVote: [], //已结束
    AlreadyVote: [], //已投票
    checked: false, //禁止投票开关
    showVote: false, //投票弹出框开关
    text: '', //投票标题
    ticket: 0, //票数
    ticket2: 0, //投票后的票数
    search: '', //搜索值
    optionId: 0, //投票id
    personId: 0, //用户id
  },
  /*监听搜索输入框的值*/
  Search(event) {
    this.setData({
      search: event.detail
    })
  },
  /*输入框搜索商品*/
  onSearch() {
    var that = this;
    //调用查询接口
    util.request(api.SearchVote, {
      title: that.data.search
    }).then(res => {
      //如果搜索字段为空,就刷新界面
      if (that.data.search == '') {
        this.onShow();
      } else {
        this.setData({
          VoteAll: res.data.searchList
        });
      }
    }).catch(res => {
      console.log('服器没有开启,使用模拟数据!')
    })
  },

  //获取全部投票信息
  loadVoteInfos() {
    util.request(api.VoteInfos).then(res => {
      this.setData({
        VoteAll: res.data.voteList
      });
    }).catch(res => {
      console.log('服器没有开启,使用模拟数据!')
    })
  },
  //获取全部已结束投票信息
  loadOverVote() {
    util.request(api.OverVote).then(res => {
      this.setData({
        OverVote: res.data.overList
      });
    }).catch(res => {
      console.log('服器没有开启,使用模拟数据!')
    })
  },
  //获取全部已投票的信息
  loadAlreadyVote() {
    util.request(api.AlreadyVote, {
      personId: this.data.personId
    }).then(res => {
      this.setData({
        AlreadyVote: res.data.alreadyList
      });
    }).catch(res => {
      console.log('服器没有开启,使用模拟数据!')
    })
  },

  //发布投票点击事件
  open_publishVote: function () {
    wx.navigateTo({
      url: '/pages/meeting/add/add',
    })
  },

  //投票弹窗点击事件
  open_vote(event) {
    var itemId = event.currentTarget.dataset.id; //投票id
    var itemText = event.currentTarget.dataset.text; //投票主题
    util.request(api.SelectTicket, {
      optionId: itemId
    }).then(res => {
      this.setData({
        text: itemText,
        showVote: true,
        ticket: res.data.ticket,
        optionId: itemId
      });
    }).catch(res => {
      console.log('服器没有开启,使用模拟数据!')
    })

  },
  //投票弹窗关闭事件
  onClose() {
    this.setData({
      showVote: false
    });
  },
  //票数绑定
  onChange(event) {
    // 用户投的票
    this.setData({
      ticket2: event.detail
    });
    console.log(this.data.ticket); //原票数
    console.log(this.data.ticket2); //新票数
  },

  // 投票确认事件
  getUserInfo(event) {
    let ticket = this.data.ticket2;
    let userInfo = wx.getStorageSync('userInfo');;
    // 构造发布投票请求参数
    const putVote = {
      optionId: this.data.optionId,
      personId: userInfo.userId
    };
    //对比如果没增长就代表没投票,并且为登录状态
    if (this.data.ticket == ticket || userInfo.userId == 0) {
      wx.showToast({
        title: '暂未投票哦',
        icon: 'error',
        duration: 2000,
        mask: true //显示透明蒙层,防止触摸穿透
      });
    } else {
      util.request(api.AddTicket, putVote).then(res => {
        console.log(res);
        wx.showToast({
          title: '投票成功',
          icon: 'sucess',
          duration: 2000,
          mask: true //显示透明蒙层,防止触摸穿透
        });
        this.onShow();
      }).catch(res => {
        console.log('服器没有开启,使用模拟数据!')
      })
    }
  },


  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },


  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
        // 从本地缓冲拿取用户id
        let userInfo = wx.getStorageSync('userInfo');
        this.setData({
          personId: userInfo.userId
        });
    this.loadVoteInfos();
    this.loadOverVote();
    this.loadAlreadyVote();
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

 

效果展示讲解:

1、查询当前登录的用户id,获取已投票和未投票信息,分别存储不同数组进行遍历显示

2、通过数据投票主题关键字进行模糊查询

3、点击投票列表进入弹窗,显示投票主题和该票数,利用进步器选择加减投票

4、必须加一票和登录后才能投票成功,并刷新界面

🌟更多解释请研究js代码

 

4.2  发布投票组件

WXML

这里用到了图片上传和下拉会议列表

<!--pages/meeting/add/add.wxml-->
<view class="img">
  <image class="upload_img" src="{{imageUrl=='' ? '/static/images/uploadimg.png':imageUrl }}" mode="aspectFit" bindtap="handleUploadImage"></image>
  <input hidden="true" type="text" name="images" value="{{imageUrl}}" />
</view>
<view style="height: 10px;"></view>
<van-cell-group>
  <van-field model:value="{{ title }}" placeholder="请输入投票主题" label="主题" border="{{ true }}" />
</van-cell-group>
<view style="height: 10px;"></view>
<!-- 会议列表 -->
<van-dropdown-menu active-color="#1989fa">
  <van-dropdown-item value="{{ value }}" options="{{ option }}" bind:change="onDropdownMenuChange" />
</van-dropdown-menu>
<view style="height: 300px;"></view>
<van-row>
  <van-col offset="8" span="8">
    <van-button plain hairline icon="add-square" type="info" style="margin-top: 25px;" bind:tap="handleVote" size="large">发起投票</van-button>
  </van-col>
</van-row>

 

WXSS

/* pages/meeting/add/add.wxss */
.img {
  margin-top: 25px;
  height: 480rpx;
}

.upload_img {
  height: 450rpx;
  width: 735rpx;
  box-shadow: 5px 8px rgb(218, 221, 221);
  border-radius: 5rpx;
}

JSON

java">{
  "navigationBarTitleText": "发起投票",
  "usingComponents": {
    "van-field": "@vant/weapp/field/index",
    "van-uploader": "@vant/weapp/uploader/index",
    "van-row": "@vant/weapp/row/index",
    "van-col": "@vant/weapp/col/index",
    "van-calendar": "@vant/weapp/calendar/index",
    "van-cell": "@vant/weapp/cell/index",
    "van-cell-group": "@vant/weapp/cell-group/index",
    "van-button": "@vant/weapp/button/index",
    "van-picker": "@vant/weapp/picker/index",
    "van-dropdown-menu": "@vant/weapp/dropdown-menu/index",
    "van-dropdown-item": "@vant/weapp/dropdown-item/index"
  }
}

WXJS

javascript">// pages/meeting/add/add.js
var app = getApp();
const api = require('../../../config/api');
const util = require('../../../utils/util.js');

Page({
  /**
   * 页面的初始数据
   */
  data: {
    imageUrl: '', //发布投票图片
    option: [{
      text: '选择会议',
      value: 0
    }], //会议选项(该是默认值)
    value: 0, //会议选项id
    optiontext: null, //会议选项标题
    title: '', //投票主题
  },

  //图片选择器
  handleUploadImage() {
    wx.chooseImage({
      count: 1,
      success: (res) => {
        const imagePath = res.tempFilePaths[0];
        // 处理选择的图片路径
        console.log('选择的图片路径:', imagePath);
        this.setData({
          imageUrl: imagePath // 更新图片路径,触发重新渲染
        });
      }
    });
  },

  //获取所有正在进行的会议
  loadMeetingInfos() {
    util.request(api.MettingInfoState).then(res => {
      //定义空数组存储数据库传来的json数据值
      let options = [];
      for (var index in res.data.listState) {
        //获取需要的字段值
        let id = res.data.listState[index].id;
        let title = res.data.listState[index].title;
        //给每个值设置对应的字段存储到数组
        options.push({
          text: title,
          value: id
        });
      }
      this.setData({
        //在option数组的内容后添加新的内容
        option: this.data.option.concat(options)
      });
    }).catch(res => {
      console.log('服器没有开启,使用模拟数据!')
    })
  },

  // 监听菜单选择事件
  onDropdownMenuChange(event) {
    //获取选择的选项值
    let value = event.detail;
    //获取option数组的value与选择的value值相同的数据
    const selectedOption = this.data.option.find(option => option.value === value);
    this.setData({
      //将数据赋值到变量中进行存储
      optiontext: selectedOption.text,
      value: selectedOption.value
    });
  },

  //发布投票
  handleVote() {
    // 获取页面中的数据
    const picture = this.data.imageUrl;
    const meetingId = this.data.value;
    const title = this.data.title;

    //判断只要有内容为空就不进行发布
    if (picture == '' || meetingId == 0 || title == '') {
      wx.showToast({
        title: '请完善投票内容',
        icon: 'error',
        duration: 2000,
        mask: true //显示透明蒙层,防止触摸穿透
      });
      //阻止运行后面的代码
      return
    }

    // 构造发布投票请求参数
    const requestData = {
      meetingid: meetingId,
      title: title,
      picture: picture
    };

    // 构造修改会议状态请求参数
    const updateData = {
        id: meetingId,
        state:5
    };

    // 发起网络请求,将数据传递给后端
    util.request(api.MeetingAddVote, requestData).then(res => {
      //修改会议状态为开启投票接口
      util.request(api.UpdateState,updateData).then(res => {console.log(res)});
      //获取页面栈返回上一个界面
      const pages = getCurrentPages() //获取页面列表
      const perpage = pages[pages.length - 1] //当前页   
      //刷新页面
      wx.navigateBack({
        delta: 1,
        //返回成功调用函数
        success: function () {
          wx.showToast({
            title: '发布成功',
            icon: 'success',
            duration: 2000,
            mask: true //显示透明蒙层,防止触摸穿透
          });
        }
      })
      //加载界面(用于刷新)
      perpage.onLoad()

      // 可以在这里进行页面跳转或其他操作
    }).catch(res => {
      // 请求失败的处理逻辑
      console.error('数据保存失败', err);
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.loadMeetingInfos();
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

效果展示讲解:

1、首先是一个图片点击事件跳转到发布投票界面

2、进入页面就开始渲染会议列表内容,获取所有会议状态为开启会议的json数据,通过遍历拿取id和标题,按照指定下拉列表组件指定属性进行复制。

3、通过微信提供的图片上传函数,将图片解析成网络路径进行访问和存储

4、最后准备发布投票:

  • 监听下拉列表数据,通过选择的值对原数组的值进行判断从而确定拿取的数据
  • 发布成功后通过获取页面栈返回上级界面,并利用生命周期同时刷新投票界面

🌟更多解释请研究js代码

 

       如你们所见,其实其中许多不足,比如用户投完票后,该选择没有在界面上消除。这里还需要做连表查询投票信息如果存在该发布的投票列表就不会再获取到;还有每当点击投票弹窗确定时,不管是否投了票,是否登录了,它都会调用一次微信登录方法,这个目前还在排查中,不知道是否是某些方法牵引到了登录功能,各位大佬有什么见解欢迎评论区留言🥰


http://www.niftyadmin.cn/n/5128940.html

相关文章

【深度学习】Transformer、GPT、BERT、Seq2Seq什么区别?

请看vcr&#xff1a;https://transformers.run/back/transformer/

数字孪生与智慧城市:开启未来智慧生活

在数字时代的浪潮中&#xff0c;数字孪生技术和智慧城市的理念相互交织&#xff0c;共同塑造了一个更智能、更可持续、更宜居的未来。数字孪生是一项前沿技术&#xff0c;将虚拟世界与现实世界相融合&#xff0c;为城市管理者和市民带来了前所未有的机遇和便捷。 数字孪生模型是…

2023年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 下列 Python 语句能够正确输出"学而时习之"五个字的是&#xff1f;&#xff08; &#xff09; A: print “…

el-table添加固定高度height后高度自适应

0 效果 1 添加自定义指令 新建目录src/directive/el-table 在el-table目录下新建文件adaptive.js import { addResizeListener, removeResizeListener } from element-ui/src/utils/resize-event// 设置表格高度const doResize async(el, binding, vnode) > {// 获取表格…

SpringMVC(四)域对象共享数据

pageContext:表示的是jsp页面的范围 HttpServletRequest:表示的是一次请求的范围 HttpSession:表示的是一次会话的范围 ServletContext:表示的是整个应用的范围 一、向请求域中共享数据&#xff1a; 1.1使用ServletAPI向request域对象共享数据 RequestMapping("test…

uniapp-图片压缩(适配H5,APP)

uniapp本身是自带压缩图片的方式的&#xff0c;但是他只适用于APP&#xff0c;做不到多端的适配&#xff0c;如果只考虑app&#xff0c;就非常容易实现了。 使用uni.compressImage()这个API即可 compressImage(url) {return new Promise((reslove, reject) > {const tempFi…

【嵌入式开发 Linux 常用命令系列 9 -- linux系统终端命令提示符设置(PS1)】

文章目录 Linux PS1 介绍PS1 纯文本和特殊的转义序列PS1 颜色设置 Linux PS1 介绍 在Linux中&#xff0c;PS1&#xff08;Prompt String 1&#xff09;是一个环境变量&#xff0c;用来定义shell命令提示符的显示内容和格式。当你在终端中输入命令时&#xff0c;PS1定义的就是那…

【Leetcode】【每日一题】【中等】1465. 切割后面积最大的蛋糕

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/maximum-area-of-a-piece-of-cak…