PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

博客列表 > 基于微信小程序的会议室预定平台开发笔记

基于微信小程序的会议室预定平台开发笔记

P粉009333381
P粉009333381 原创
2022年09月23日 07:14:40 515浏览

业务背景

会议室是一个单位或部门的共用资源,但在使用的时候往往会遇到时间冲突、预约困难、不方便协调等问题。目前大部分公司是统一在公司群聊中预约,每次预约时,都需要翻一下聊天记录,了解是否有人预定以及预定时间等。如果冲突则需要找到相关联系人进行沟通。查找历史预约记录麻烦。而现在员工人人都有微信,基于微信环境下的小程序,不用安装独立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代码

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议