Blogger Information
Blog 2
fans 0
comment 0
visits 1004
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
基于微信小程序的会议室预定平台开发笔记
P粉009333381
Original
555 people have browsed it

业务背景

会议室是一个单位或部门的共用资源,但在使用的时候往往会遇到时间冲突、预约困难、不方便协调等问题。目前大部分公司是统一在公司群聊中预约,每次预约时,都需要翻一下聊天记录,了解是否有人预定以及预定时间等。如果冲突则需要找到相关联系人进行沟通。查找历史预约记录麻烦。而现在员工人人都有微信,基于微信环境下的小程序,不用安装独立APP,访问方便。所以我们可以基于小程序,借助于会议室预约系统改善这种情况,实现会议室资源的最优使用

需求分析

在这里插入图片描述

数据库设计

  1. EnrollModel.DB_STRUCTURE = {
  2. _pid: 'string|true',
  3. ENROLL_ID: 'string|true',
  4. ENROLL_TITLE: 'string|true|comment=标题',
  5. ENROLL_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中',
  6. ENROLL_CATE_ID: 'string|true|default=0|comment=分类',
  7. ENROLL_CATE_NAME: 'string|false|comment=分类冗余',
  8. ENROLL_CANCEL_SET: 'int|true|default=1|comment=取消设置 0=不允,1=允许,2=仅截止前可取消,3=审核后不可取消',
  9. ENROLL_EDIT_SET: 'int|true|default=1|comment=修改 0=不允,1=允许,2=仅截止前可,3=审核后不可修改',
  10. ENROLL_CHECK_SET: 'int|true|default=0|comment=审核 0=不需要审核,1=需要审核',
  11. ENROLL_ORDER: 'int|true|default=9999',
  12. ENROLL_VOUCH: 'int|true|default=0',
  13. ENROLL_FORMS: 'array|true|default=[]',
  14. ENROLL_OBJ: 'object|true|default={}',
  15. ENROLL_JOIN_FORMS: 'array|true|default=[]',
  16. ENROLL_QR: 'string|false',
  17. ENROLL_VIEW_CNT: 'int|true|default=0',
  18. ENROLL_JOIN_CNT: 'int|true|default=0',
  19. ENROLL_ADD_TIME: 'int|true',
  20. ENROLL_EDIT_TIME: 'int|true',
  21. ENROLL_ADD_IP: 'string|false',
  22. ENROLL_EDIT_IP: 'string|false',
  23. };
  24. EnrollJoinModel.DB_STRUCTURE = {
  25. _pid: 'string|true',
  26. ENROLL_JOIN_ID: 'string|true',
  27. ENROLL_JOIN_ENROLL_ID: 'string|true|comment=报名PK',
  28. ENROLL_JOIN_IS_ADMIN: 'int|true|default=0|comment=是否管理员添加 0/1',
  29. ENROLL_JOIN_DAY: 'string|false|comment=预约日期',
  30. ENROLL_JOIN_START: 'string|false|comment=开始时间',
  31. ENROLL_JOIN_END: 'string|false|comment=结束时间',
  32. ENROLL_JOIN_END_POINT: 'string|false|comment=结束时间末尾',
  33. ENROLL_JOIN_USER_ID: 'string|true|comment=用户ID',
  34. ENROLL_JOIN_FORMS: 'array|true|default=[]|comment=表单',
  35. ENROLL_JOIN_OBJ: 'object|true|default={}',
  36. ENROLL_JOIN_STATUS: 'int|true|default=1|comment=状态 0=待审核 1=报名成功, 99=审核未过',
  37. ENROLL_JOIN_REASON: 'string|false|comment=审核拒绝或者取消理由',
  38. ENROLL_JOIN_LAST_TIME: 'int|true|default=0',
  39. ENROLL_JOIN_ADD_TIME: 'int|true',
  40. ENROLL_JOIN_EDIT_TIME: 'int|true',
  41. ENROLL_JOIN_ADD_IP: 'string|false',
  42. ENROLL_JOIN_EDIT_IP: 'string|false',
  43. };

UI设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

核心代码

  1. class EnrollService extends BaseProjectService {
  2. // 获取当前登记状态
  3. getJoinStatusDesc(enroll) {
  4. return '进行中';
  5. }
  6. /** 浏览信息 */
  7. async viewEnroll(userId, id) {
  8. let fields = '*';
  9. let where = {
  10. _id: id,
  11. ENROLL_STATUS: EnrollModel.STATUS.COMM
  12. }
  13. let enroll = await EnrollModel.getOne(where, fields);
  14. if (!enroll) return null;
  15. EnrollModel.inc(id, 'ENROLL_VIEW_CNT', 1);
  16. // 判断是否有登记
  17. let whereJoin = {
  18. ENROLL_JOIN_USER_ID: userId,
  19. ENROLL_JOIN_ENROLL_ID: id,
  20. ENROLL_JOIN_STATUS: ['in', [EnrollJoinModel.STATUS.WAIT, EnrollJoinModel.STATUS.SUCC]]
  21. }
  22. let enrollJoin = await EnrollJoinModel.getOne(whereJoin);
  23. if (enrollJoin) {
  24. enroll.myEnrollJoinId = enrollJoin._id;
  25. enroll.myEnrollJoinTag = (enrollJoin.ENROLL_JOIN_STATUS == EnrollJoinModel.STATUS.WAIT) ? '待审核' : '已预约';
  26. }
  27. else {
  28. enroll.myEnrollJoinId = '';
  29. enroll.myEnrollJoinTag = '';
  30. }
  31. return enroll;
  32. }
  33. /** 取得分页列表 */
  34. async getEnrollList({
  35. search, // 搜索条件
  36. sortType, // 搜索菜单
  37. sortVal, // 搜索菜单
  38. orderBy, // 排序
  39. page,
  40. size,
  41. isTotal = true,
  42. oldTotal
  43. }) {
  44. orderBy = orderBy || {
  45. 'ENROLL_ORDER': 'asc',
  46. 'ENROLL_ADD_TIME': 'desc'
  47. };
  48. let fields = 'ENROLL_STOP,ENROLL_JOIN_CNT,ENROLL_OBJ,ENROLL_VIEW_CNT,ENROLL_TITLE,ENROLL_ORDER,ENROLL_STATUS,ENROLL_CATE_NAME';
  49. let where = {};
  50. where.and = {
  51. _pid: this.getProjectId() //复杂的查询在此处标注PID
  52. };
  53. where.and.ENROLL_STATUS = EnrollModel.STATUS.COMM; // 状态
  54. if (util.isDefined(search) && search) {
  55. where.or = [{
  56. ENROLL_TITLE: ['like', search]
  57. },];
  58. } else if (sortType && util.isDefined(sortVal)) {
  59. // 搜索菜单
  60. switch (sortType) {
  61. case 'cateId': {
  62. if (sortVal) where.and.ENROLL_CATE_ID = String(sortVal);
  63. break;
  64. }
  65. case 'sort': {
  66. orderBy = this.fmtOrderBySort(sortVal, 'ENROLL_ADD_TIME');
  67. break;
  68. }
  69. }
  70. }
  71. return await EnrollModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);
  72. }
  73. // 获取某天某会议室预约情况
  74. async getEnrollJoinByDay(enrollId, day) {
  75. let where = {
  76. ENROLL_JOIN_DAY: day,
  77. ENROLL_JOIN_ENROLL_ID: enrollId,
  78. };
  79. return EnrollJoinModel.getAll(where);
  80. }
  81. /** 取得我的登记分页列表 */
  82. async getMyEnrollJoinList(userId, {
  83. search, // 搜索条件
  84. sortType, // 搜索菜单
  85. sortVal, // 搜索菜单
  86. orderBy, // 排序
  87. page,
  88. size,
  89. isTotal = true,
  90. oldTotal
  91. }) {
  92. orderBy = orderBy || {
  93. 'ENROLL_JOIN_ADD_TIME': 'desc'
  94. };
  95. let fields = 'ENROLL_JOIN_OBJ,ENROLL_JOIN_DAY,ENROLL_JOIN_START,ENROLL_JOIN_END,ENROLL_JOIN_END_POINT,ENROLL_JOIN_LAST_TIME,ENROLL_JOIN_REASON,ENROLL_JOIN_ENROLL_ID,ENROLL_JOIN_STATUS,ENROLL_JOIN_ADD_TIME,enroll.ENROLL_TITLE,enroll.ENROLL_EDIT_SET,enroll.ENROLL_CANCEL_SET';
  96. let where = {
  97. ENROLL_JOIN_USER_ID: userId
  98. };
  99. if (util.isDefined(search) && search) {
  100. where['enroll.ENROLL_TITLE'] = {
  101. $regex: '.*' + search,
  102. $options: 'i'
  103. };
  104. } else if (sortType) {
  105. // 搜索菜单
  106. switch (sortType) {
  107. case 'timedesc': { //按时间倒序
  108. orderBy = {
  109. 'ENROLL_JOIN_ADD_TIME': 'desc'
  110. };
  111. break;
  112. }
  113. case 'timeasc': { //按时间正序
  114. orderBy = {
  115. 'ENROLL_JOIN_ADD_TIME': 'asc'
  116. };
  117. break;
  118. }
  119. case 'succ': {
  120. where.ENROLL_JOIN_STATUS = EnrollJoinModel.STATUS.SUCC;
  121. break;
  122. }
  123. case 'wait': {
  124. where.ENROLL_JOIN_STATUS = EnrollJoinModel.STATUS.WAIT;
  125. break;
  126. }
  127. case 'cancel': {
  128. where.ENROLL_JOIN_STATUS = EnrollJoinModel.STATUS.ADMIN_CANCEL;
  129. break;
  130. }
  131. }
  132. }
  133. let joinParams = {
  134. from: EnrollModel.CL,
  135. localField: 'ENROLL_JOIN_ENROLL_ID',
  136. foreignField: '_id',
  137. as: 'enroll',
  138. };
  139. let result = await EnrollJoinModel.getListJoin(joinParams, where, fields, orderBy, page, size, isTotal, oldTotal);
  140. return result;
  141. }
  142. /**
  143. * 获取从某天开始有预约的日期
  144. * @param {*} fromDay 日期 Y-M-D
  145. */
  146. async getEnrollJoinHasDaysFromDay(fromDay) {
  147. let where = {
  148. ENROLL_JOIN_DAY: ['>=', fromDay],
  149. };
  150. let fields = 'ENROLL_JOIN_DAY';
  151. let list = await EnrollJoinModel.distinct(where, fields);
  152. return list;
  153. }
  154. /** 按天获取所有预定项目 */
  155. async getEnrollJoinAllListByDay(day) {
  156. let where = {
  157. ENROLL_JOIN_STATUS: EnrollJoinModel.STATUS.SUCC,
  158. ENROLL_JOIN_DAY: day,
  159. };
  160. let orderBy = {
  161. 'ENROLL_JOIN_START': 'asc',
  162. 'ENROLL_JOIN_ADD_TIME': 'desc'
  163. };
  164. let fields = 'ENROLL_JOIN_START,ENROLL_JOIN_END_POINT,ENROLL_JOIN_OBJ';
  165. let list = await EnrollJoinModel.getAll(where, fields, orderBy);
  166. let retList = [];
  167. for (let k = 0; k < list.length; k++) {
  168. console.log(list[k])
  169. let node = {};
  170. node.timeDesc = list[k].ENROLL_JOIN_START;
  171. node.title = list[k].ENROLL_JOIN_OBJ.name;
  172. node._id = list[k]._id;
  173. retList.push(node);
  174. }
  175. return retList;
  176. }
  177. /** 取得我的登记详情 */
  178. async getMyEnrollJoinDetail(enrollJoinId) {
  179. let fields = '*';
  180. let where = {
  181. _id: enrollJoinId
  182. };
  183. let enrollJoin = await EnrollJoinModel.getOne(where, fields);
  184. if (enrollJoin) {
  185. enrollJoin.enroll = await EnrollModel.getOne(enrollJoin.ENROLL_JOIN_ENROLL_ID, 'ENROLL_TITLE');
  186. }
  187. return enrollJoin;
  188. }
  189. //################## 登记
  190. // 登记
  191. async enrollJoin(userId, enrollId, start, end, endPoint, day, forms) {
  192. // 登记是否结束
  193. let whereEnroll = {
  194. _id: enrollId,
  195. ENROLL_STATUS: EnrollModel.STATUS.COMM
  196. }
  197. let enroll = await EnrollModel.getOne(whereEnroll);
  198. if (!enroll)
  199. this.AppError('该' + ENROLL_NAME + '不存在或者已经停止');
  200. // 时段是否冲突 TODO
  201. // 入库
  202. let data = {
  203. ENROLL_JOIN_USER_ID: userId,
  204. ENROLL_JOIN_ENROLL_ID: enrollId,
  205. ENROLL_JOIN_START: start,
  206. ENROLL_JOIN_END: end,
  207. ENROLL_JOIN_END_POINT: endPoint,
  208. ENROLL_JOIN_DAY: day,
  209. ENROLL_JOIN_STATUS: (enroll.ENROLL_CHECK_SET == 0) ? EnrollJoinModel.STATUS.SUCC : EnrollJoinModel.STATUS.WAIT,
  210. ENROLL_JOIN_FORMS: forms,
  211. ENROLL_JOIN_OBJ: dataUtil.dbForms2Obj(forms),
  212. }
  213. let enrollJoinId = await EnrollJoinModel.insert(data);
  214. // 统计数量
  215. this.statEnrollJoin(enrollId);
  216. let check = enroll.ENROLL_CHECK_SET;
  217. return { enrollJoinId, check }
  218. }
  219. // 修改登记
  220. async enrollJoinEdit(userId, enrollId, enrollJoinId, forms) {
  221. let whereJoin = {
  222. _id: enrollJoinId,
  223. ENROLL_JOIN_USER_ID: userId,
  224. ENROLL_JOIN_ENROLL_ID: enrollId,
  225. ENROLL_JOIN_STATUS: ['in', [EnrollJoinModel.STATUS.WAIT, EnrollJoinModel.STATUS.SUCC]],
  226. }
  227. let enrollJoin = await EnrollJoinModel.getOne(whereJoin);
  228. if (!enrollJoin)
  229. this.AppError('该' + ENROLL_NAME + '记录不存在或者已经被系统取消');
  230. // 登记是否结束
  231. let whereEnroll = {
  232. _id: enrollId,
  233. ENROLL_STATUS: EnrollModel.STATUS.COMM
  234. }
  235. let enroll = await EnrollModel.getOne(whereEnroll);
  236. if (!enroll)
  237. this.AppError('该' + ENROLL_NAME + '不存在或者已经停止');
  238. if (enroll.ENROLL_EDIT_SET == 0)
  239. this.AppError('该' + ENROLL_NAME + '不允许修改资料');
  240. if (enroll.ENROLL_EDIT_SET == 3
  241. && enroll.ENROLL_CHECK_SET == 1
  242. && enrollJoin.ENROLL_JOIN_STATUS == EnrollJoinModel.STATUS.SUCC
  243. )
  244. this.AppError('该' + ENROLL_NAME + '已通过审核,不能修改资料');
  245. let data = {
  246. ENROLL_JOIN_FORMS: forms,
  247. ENROLL_JOIN_OBJ: dataUtil.dbForms2Obj(forms),
  248. ENROLL_JOIN_LAST_TIME: this._timestamp,
  249. }
  250. await EnrollJoinModel.edit(whereJoin, data);
  251. }
  252. async statEnrollJoin(id) {
  253. let where = {
  254. ENROLL_JOIN_ENROLL_ID: id,
  255. ENROLL_JOIN_STATUS: ['in', [EnrollJoinModel.STATUS.WAIT, EnrollJoinModel.STATUS.SUCC]]
  256. }
  257. let cnt = await EnrollJoinModel.count(where);
  258. await EnrollModel.edit(id, { ENROLL_JOIN_CNT: cnt });
  259. }
  260. /** 登记前获取关键信息 */
  261. async detailForEnrollJoin(userId, enrollId, enrollJoinId = '') {
  262. let fields = 'ENROLL_JOIN_FORMS, ENROLL_TITLE';
  263. let where = {
  264. _id: enrollId,
  265. ENROLL_STATUS: EnrollModel.STATUS.COMM
  266. }
  267. let enroll = await EnrollModel.getOne(where, fields);
  268. if (!enroll)
  269. this.AppError('该' + ENROLL_NAME + '不存在');
  270. let joinMy = null;
  271. if (enrollJoinId) {
  272. // 编辑
  273. let whereMy = {
  274. ENROLL_JOIN_USER_ID: userId,
  275. _id: enrollJoinId
  276. }
  277. joinMy = await EnrollJoinModel.getOne(whereMy);
  278. enroll.join = {
  279. start: joinMy.ENROLL_JOIN_START,
  280. end: joinMy.ENROLL_JOIN_END,
  281. endPoint: joinMy.ENROLL_JOIN_END_POINT,
  282. day: joinMy.ENROLL_JOIN_DAY,
  283. }
  284. }
  285. else {
  286. // 取出本人最近一次的填写表单
  287. /*
  288. let whereMy = {
  289. ENROLL_JOIN_USER_ID: userId,
  290. }
  291. let orderByMy = {
  292. ENROLL_JOIN_ADD_TIME: 'desc'
  293. }
  294. joinMy = await EnrollJoinModel.getOne(whereMy, 'ENROLL_JOIN_FORMS', orderByMy);*/
  295. }
  296. let myForms = joinMy ? joinMy.ENROLL_JOIN_FORMS : [];
  297. enroll.myForms = myForms;
  298. return enroll;
  299. }
  300. /** 取消我的登记 只有成功和待审核可以取消 取消即为删除记录 */
  301. async cancelMyEnrollJoin(userId, enrollJoinId) {
  302. let where = {
  303. ENROLL_JOIN_USER_ID: userId,
  304. _id: enrollJoinId,
  305. ENROLL_JOIN_STATUS: ['in', [EnrollJoinModel.STATUS.WAIT, EnrollJoinModel.STATUS.SUCC]]
  306. };
  307. let enrollJoin = await EnrollJoinModel.getOne(where);
  308. if (!enrollJoin) {
  309. this.AppError('未找到可取消的记录');
  310. }
  311. let enroll = await EnrollModel.getOne(enrollJoin.ENROLL_JOIN_ENROLL_ID);
  312. if (!enroll)
  313. this.AppError('该' + ENROLL_NAME + '不存在');
  314. if (enroll.ENROLL_CANCEL_SET == 0)
  315. this.AppError('该' + ENROLL_NAME + '不能取消');
  316. if (enroll.ENROLL_CANCEL_SET == 3
  317. && enroll.ENROLL_CHECK_SET == 1
  318. && enrollJoin.ENROLL_JOIN_STATUS == EnrollJoinModel.STATUS.SUCC
  319. )
  320. this.AppError('该' + ENROLL_NAME + '已通过审核,不能取消');
  321. await EnrollJoinModel.del(where);
  322. this.statEnrollJoin(enrollJoin.ENROLL_JOIN_ENROLL_ID);
  323. }
  324. }

后台管理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

git代码

git代码

Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post