Because recently want to practice the small program cloud development ability, so design and develop a simple voting application, welcome interested in learning and exchange.

Code warehouse https://github.com/luosijie/m…

Because the applet [Individual Developer] is not open in the [Vote] category, it cannot be previewed online. I’ll show you a few screenshots of the application

Database design

I’m going to use three sets

1. Users (collection of users)

Basically, save the user’s userInfo data directly

{ "_id":"023ce9555ff068de0314b5521c313ee6", "OPENID":"oZK45EoiyFzv... 7R64I", "nickName":"LSJ", "gender":1, "language":"zh_CN", "city":"Xiamen", "province": "Fujian", "country":"China", "avatarUrl":"https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTL9lhZHZdYsMx3mjhZZYbbE5OZhUqUefNtsibkhdrSTIdpdhzv34lYHXtafM juoibJ8JwTj5VM76CkA/132" }

2. Votes

{" _id ":" 21 ded5cb5ff5f0530407988a4e8f18a5 ", / / the only id "creator" : "o - ZK45EoiyFzvevQyQTSZUV7R64I", / / sponsor "title" : "aston big as da", / / title "desc" : "aston aston, / / describe" startTime ":" 2021-1-7 ", / / start date "endTime" : "2021-1-8", // end date "state":"ing" // state}

3. Options

{" _id ":" be7fb3985ff5f05403068303431d580b ", / / the only id "vote_id" : "21 ded5cb5ff5f0530407988a4e8f18a5", // the voting _id of the option corresponding to "title":" Aston big big ", // the title" desc":" Aston big big big ", / / description of "image" : "http://tmp/2jVXjjLScAyNf0dffe2c5fc6479bee73fe954b64a3e7.png", / / illustrated "users" : "o - ZK45EoiyFzvevQyQTSZUV7R64I"] / / the option of voters}

Cloud function development

Six cloud functions have been written

1. AddRecord adds a new voting record

/** * New voting record * @Param {String} title * @Param {String} desc description * @Param {String} startTime start date * @Param {String} EndTime * @Param {String} anonymous * @Param {String} min Allow small number of votes * @Param {String} Max Allow maximum number of votes * @Param {String} Max Type voting type: normal; */ const cloud = require('wx-server-sdk') cloud.init({env: void (); cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const voteCollection = db.collection('votes') const data = { Creator: wxContext. openId, // initiator: event.title, desc: event.desc, startTime: event.startTime, endTime: event.endTime, anonymous: event.anonymous, min: event.min, max: event.max, type: event.type, state: // VOTES: New Record const res = await votecollection. add({data}) // Options: Options = event.options const optionCollection = db.collection('options') const optionPromise = options.map( ele => { const option = { vote_id: res._id, ... ele } return optionCollection.add({ data: Option})}) let resOptions = await Promise. All (optionPromise) resOptions = resOptions. Map (e => e =._id {success: true, message: 'New vote succeeded ',... res } }

2. GetRecordDetail gets the voting details

/ vote for details * * * * @ param {String} _id voting _id * @ return {Object} * / const data cloud = the require (' wx - server - SDK) cloud. The init ({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, Context) => {const _id = event._id const openID = cloud.getWxContext ().openID // Find the voting data in the collection const voteCollection = Order. collection('votes') // Const voteQuery = await votecollection.aggregate ().match({_id}).lookup({from: 'users', localField: 'creator', foreignField: 'OPENID', as: 'creator' }) .end() let vote = {} if (voteQuery && voteQuery.list.length) { vote = voteQuery.list[0] vote.creator = Vote.isOwner = vote.creator.openId === = openId // Find the option data in the collection const optionsCollection = db.collection('options') const optionsQuary = await optionsCollection .aggregate() .match({ vote_id: _id }) .lookup({ from: 'users', localField: 'users', foreignField: 'OPENID', as: 'Users'}).end() vote.options = optionsCary.list // Let votedTotal = 0 vote.options.foreach (e => {if (e sers &&e sers. Length) {votedTotal += e.sers. Length}}) vote.votedTotal = votedTotal // If (vote.state) is used to calculate the current voting status ! == 'end') {if (new Date().getTime() < new Date(vote.startTime).getTime()) {vote.state = 'pre'})  (new Date().getTime() > new Date(vote.endTime).getTime()) { vote.state = 'end' } } return { success: true, data: Vote}} else {return {success: false, message: 'vote information not found'}}

3. The vote operation

/** * Voting Operations * @Param {String} voteID voteID * @Param {String} optionID option _ID * @Return {Object} Voting results */ const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, context) => { const _id = event.optionId const vote_id = event.voteId const OPENID = cloud.getWXContext().OPENID // Data const options = db.collection('options') let voteOptions = await options. Where ({vote_id}).get() VoteOptions = voteOptions. Data // Let curoptionUsers = [] for (let I = 0; i < voteOptions.length; I ++) {const Users = VoteOptions [I].Users if (Users && Users.length) {if (VoteOptions [I]._id === = _id) {if (VoteOptions [I]._id === _id); {curoptionUsers = Users} if (Users && Users.length) {// OpenID repeat - Voted -> return if (User.indexOf (OpenID) >-1) {curoptionUsers = Users} if (User.indexOf (OpenID) >-1) { return { success: false, message: 'You have voted'}}}}} // No vote -> inserts current user openID into the corresponding field curoptionUsers.push (openID) const res = await options. Where ({_id }).update({data: {users: curoptionUsers}}) return {success: true, data: res, message: 'Voted successfully'}}).update({data: {users: curoptionUsers}}) return {success: true, data: res, message: 'Voted successfully'}}

4. GetRecordPage gets my voting record page

/** * Get my voting record pages * @Param {Number} No page Number * @Param {Number} Size Page Number * @Return {Object} Voting data list and total */ const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, Context) => {const WxContext = cloud.getWxContext () const size = event.size // WxContext. openID const VOteCollection = data.collection (' VOTES ') // Find the Voting Data in the Collection const VOTES = await voteCollection.aggregate() .match({ creator: OPENID }) .lookup({ from: 'options', localField: '_id', foreignField: 'vote_id', as: 'options' }) .sort({ _id: Skip ((no-1) * size).limit(size).end() // const total = await votecollection.count () let data = Order. list // votes if (data.length) {data = data.map(e => {if (e.state! == 'end') {if (new Date().getTime() < new Date(e.StartTime).getTime()) {e.State = 'pre'}} Date().getTime() > new Date(e.enerdTime).getTime()) {e.rate = 'end'}} let votedTotal = 0 const options = e.options options.forEach(o => { if (o.users && o.users.length) { votedTotal += o.users.length } }) delete e.options return { ... e, votedTotal } }) } return { total, data } }

Login in

/** ** Login register * @param {String} OpenId getWxContext () * @return {Object} with book data */ const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, Context) => {const WxContext = cloud.getWxContext () // Find the user data in the collection const UserCollection = db.collection('users') const users = await userCollection.where({ OPENID: WxContext.openID}).get() let user if (Users && Users.data.length) {// User already exists - direct assign user data user = Users.data [0]} else {// User = {openId: wxContext.openId,... Event. UserInfo} await UserCollect. add({data: user})} // return user data - front end to cache return {... user } }

6. CheckImage verifies the validity of the image

FileID * @return {Number} 0: Failed to check the fileID; */ const cloud = require('wx-server-sdk') cloud.init({env: require('wx-server-sdk') cloud.init({env: require('wx-server-sdk') cloud.DYNAMIC_CURRENT_ENV }) exports.main = async (event, Context) => {const contentType = 'image/ PNG 'const fileID = event.fileID try {// fileID const file = await Cloud.downloadFile ({fileID}) const value = file.fileContent // ImgSecCheck Check through interfaces are not wrong/media/necessary parameters {contentType, value} const result = await cloud. Openapi. Security. ImgSecCheck ({media: { contentType, value } }) return 1 } catch (err) { return 0 } }

The front-end development

The development of the small program end is based on the MPX framework produced by Didi’s front-end team

I’m not going to post the code here because the UI is a little bit simpler

Interested in welcome to https://github.com/luosijie/m… To understand

Thanks for reading!