可研
小区业主决策投票小程序: 便于业主参与社区事务的决策,通过网络投票的形式,大大节省了业委会和业主时间,也提高了投票率。其主要功能:通过身份证、业主证或其他方式确认用户身份;小区管理人员或业委会可以发起投票,设置投票主题、选项和截止日期;业主可选择自己的选项进行投票;投票结束后实时展示投票结果,包括各选项得票数和比例,并确保用户数据和投票结果的安全;该项目简洁、直观的界面,方便业主快速上手。
功能规划
数据库设计
VoteJoinModel.DB_STRUCTURE = {_pid: 'string|true',VOTE_JOIN_ID: 'string|true',VOTE_JOIN_USER_ID: 'string|true|comment=用户ID',VOTE_JOIN_VOTE_ID: 'string|true|comment=投票PK',VOTE_JOIN_SELECTED: 'array|true|default=[]|comment=投票项目选择',VOTE_JOIN_CNT: 'int|true|default=0|comment=投票项目数量',VOTE_JOIN_VOTE_TITLE: 'string|false|comment=投票项目冗余',VOTE_JOIN_ITEM_LABEL: 'array|false|comment=投票选项冗余',VOTE_JOIN_ADD_TIME: 'int|true',VOTE_JOIN_EDIT_TIME: 'int|true',VOTE_JOIN_ADD_IP: 'string|false',VOTE_JOIN_EDIT_IP: 'string|false',
};oteModel.DB_STRUCTURE = {_pid: 'string|true',VOTE_ID: 'string|true',VOTE_TITLE: 'string|true|comment=标题',VOTE_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中',VOTE_CATE_ID: 'string|true|default=0|comment=分类',VOTE_CATE_NAME: 'string|false|comment=分类冗余',VOTE_CANCEL_SET: 'int|true|default=1|comment=取消设置 0=不允,1=允许,2=仅截止前可取消',VOTE_START: 'int|true|comment=开始时间',VOTE_END: 'int|true|comment=截止时间',VOTE_ORDER: 'int|true|default=9999',VOTE_VOUCH: 'int|true|default=0',VOTE_ITEM: 'array|false|default=[]|comment=投票项目 [{label=名称,cnt=数量}]',VOTE_TYPE: 'int|true|default=0|comment=形态 0-单选 1=多选',VOTE_USER: 'array|false|default=[]|comment=投票用户[{id,time,selected}]',VOTE_FORMS: 'array|true|default=[]',VOTE_OBJ: 'object|true|default={}',VOTE_QR: 'string|false',VOTE_VIEW_CNT: 'int|true|default=0',VOTE_USER_CNT: 'int|true|default=0',VOTE_CNT: 'int|true|default=0',VOTE_ADD_TIME: 'int|true',VOTE_EDIT_TIME: 'int|true',VOTE_ADD_IP: 'string|false',VOTE_EDIT_IP: 'string|false',
};
核心实现
class PassportService extends BaseProjectService {// 注册async register(userId, {mobile,name,forms,status}) {// 判断是否存在let where = {USER_MINI_OPENID: userId}let cnt = await UserModel.count(where);if (cnt > 0)return await this.login(userId);where = {USER_MOBILE: mobile}cnt = await UserModel.count(where);if (cnt > 0) this.AppError('该手机已注册');// 入库let data = {USER_MINI_OPENID: userId,USER_MOBILE: mobile,USER_NAME: name,USER_OBJ: dataUtil.dbForms2Obj(forms),USER_FORMS: forms,USER_STATUS: Number(status)}await UserModel.insert(data);return await this.login(userId);}/** 获取手机号码 */async getPhone(cloudID) {let cloud = cloudBase.getCloud();let res = await cloud.getOpenData({list: [cloudID], // 假设 event.openData.list 是一个 CloudID 字符串列表});if (res && res.list && res.list[0] && res.list[0].data) {let phone = res.list[0].data.phoneNumber;return phone;} elsereturn '';}/** 取得我的用户信息 */async getMyDetail(userId) {let where = {USER_MINI_OPENID: userId}let fields = 'USER_MOBILE,USER_NAME,USER_FORMS,USER_OBJ,USER_STATUS,USER_CHECK_REASON'return await UserModel.getOne(where, fields);}/** 修改用户资料 */async editBase(userId, {mobile,name,forms}) {let whereMobile = {USER_MOBILE: mobile,USER_MINI_OPENID: ['<>', userId]}let cnt = await UserModel.count(whereMobile);if (cnt > 0) this.AppError('该手机已注册');let where = {USER_MINI_OPENID: userId}let user = await UserModel.getOne(where);if (!user) return;let data = {USER_MOBILE: mobile,USER_NAME: name,USER_OBJ: dataUtil.dbForms2Obj(forms),USER_FORMS: forms,};if (user.USER_STATUS == UserModel.STATUS.UNCHECK)data.USER_STATUS = UserModel.STATUS.UNUSE;await UserModel.edit(where, data);}/** 登录 */async login(userId) {let where = {'USER_MINI_OPENID': userId};let fields = 'USER_ID,USER_MINI_OPENID,USER_NAME,USER_PIC,USER_STATUS';let user = await UserModel.getOne(where, fields);let token = {};if (user) {// 正常用户token.id = user.USER_MINI_OPENID;token.key = user.USER_ID;token.name = user.USER_NAME;token.pic = user.USER_PIC;token.status = user.USER_STATUS;// 异步更新最近更新时间let dataUpdate = {USER_LOGIN_TIME: this._timestamp};UserModel.edit(where, dataUpdate);UserModel.inc(where, 'USER_LOGIN_CNT', 1);} elsetoken = null;return {token};}}
UI设计
ADMIN UI
GIT代码下载
点击下载