diff --git a/TODOs.md b/TODOs.md index 4e2377b..70eaa01 100644 --- a/TODOs.md +++ b/TODOs.md @@ -4,6 +4,8 @@ 小程序首页密码修改 +小程序端用户头像 + 大门 人员进出 后台管理(进出日志) 后台订单管理页 @@ -16,16 +18,24 @@ 后台管理两个端分开 +后台管理 按照id进行筛选 + 体温上报添加一个按钮 可以删除当日填报 项目部署到服务器 +& 演示时快速创建账号 & 小程序提审(提审时隐藏小商店 调试按钮、上帝按钮) & 发给老班看一看 数据库填充测试数据(以及创建一些测试账号)并备份,线上演示数据修改删除避免真删 +项目中的TODO + +项目开发中遇到的问题 +小程序双端不一致的问题,参数转义,页面CSS样式是不完全一样的。 + # IP 配置 内网穿透:106.75.217.14 diff --git a/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/pojo/AccessLog.java b/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/pojo/AccessLog.java new file mode 100644 index 0000000..2498df4 --- /dev/null +++ b/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/pojo/AccessLog.java @@ -0,0 +1,20 @@ +package com.cxyxiaomo.epp.common.pojo; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +@Data +@NoArgsConstructor +@Accessors(chain = true) // 链式写法 +public class AccessLog implements Serializable { + private Long id; + private Date time; + private Integer userId; + private String userRealName; + private Long gateId; + private String type; +} diff --git a/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/query/AccessLogQuery.java b/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/query/AccessLogQuery.java new file mode 100644 index 0000000..7467107 --- /dev/null +++ b/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/query/AccessLogQuery.java @@ -0,0 +1,28 @@ +package com.cxyxiaomo.epp.common.query; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +// 数据库关系映射 + +@Data +@NoArgsConstructor +@Accessors(chain = true) // 链式写法 +// 微服务必须要实现Serializable +public class AccessLogQuery implements Serializable { + + private String id; + + private Long startTime, endTime; + + private Integer userId; + + private String userRealName; + + private Long gateId; + + private String type; +} diff --git a/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/vo/AccessLogVO.java b/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/vo/AccessLogVO.java new file mode 100644 index 0000000..f9adaa0 --- /dev/null +++ b/backend/microservice-common/src/main/java/com/cxyxiaomo/epp/common/vo/AccessLogVO.java @@ -0,0 +1,92 @@ +package com.cxyxiaomo.epp.common.vo; + +import com.cxyxiaomo.epp.common.pojo.AccessLog; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.springframework.beans.BeanUtils; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +// 数据库关系映射 + +@Data +@NoArgsConstructor +@Accessors(chain = true) // 链式写法 +// 微服务必须要实现Serializable +public class AccessLogVO implements Serializable { + + private String id; + private Long timestamp; + private Integer userId; + private String userRealName; + private String gateId; + private String type; + + public static AccessLogVO convertFrom(AccessLog accessLog) { + if (accessLog == null) { + return null; + } + AccessLogVO accessLogVO = new AccessLogVO(); + BeanUtils.copyProperties(accessLog, accessLogVO); + Date time = accessLog.getTime(); + accessLogVO.setTimestamp(time.getTime()); + if (Objects.nonNull(accessLog.getId())) { + accessLogVO.setId(String.valueOf(accessLog.getId())); + } + if (Objects.nonNull(accessLog.getGateId())) { + accessLogVO.setGateId(String.valueOf(accessLog.getGateId())); + } + return accessLogVO; + } + + public static List convertFrom(List accessLogList) { + if (accessLogList == null) { + return null; + } + List accessLogVOList = accessLogList.stream() + .map(AccessLogVO::convertFrom).collect(Collectors.toList()); + return accessLogVOList; + } + + public static AccessLog convertTo(AccessLogVO accessLogVO) { + if (accessLogVO == null) { + return null; + } + AccessLog accessLog = new AccessLog(); + BeanUtils.copyProperties(accessLogVO, accessLog); + + Long timestamp = accessLogVO.getTimestamp(); + if (timestamp != null) { + Date date = new Date(timestamp); + accessLog.setTime(date); + } + + try { + if (Objects.nonNull(accessLogVO.getId())) { + Long accessLogId = Long.valueOf(accessLogVO.getId()); + accessLog.setId(accessLogId); + } else { + accessLog.setId(null); + } + } catch (Exception e) { + accessLog.setId(null); + } + + try { + if (Objects.nonNull(accessLogVO.getGateId())) { + Long gateId = Long.valueOf(accessLogVO.getGateId()); + accessLog.setGateId(gateId); + } else { + accessLog.setGateId(null); + } + } catch (Exception e) { + accessLog.setGateId(null); + } + return accessLog; + } +} diff --git a/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/controller/AccessLogController.java b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/controller/AccessLogController.java new file mode 100644 index 0000000..db3a9be --- /dev/null +++ b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/controller/AccessLogController.java @@ -0,0 +1,185 @@ +package com.cxyxiaomo.epp.access.controller; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.cxyxiaomo.epp.PageTable.enums.AddType; +import com.cxyxiaomo.epp.PageTable.enums.EditType; +import com.cxyxiaomo.epp.PageTable.enums.FieldType; +import com.cxyxiaomo.epp.PageTable.enums.SearchType; +import com.cxyxiaomo.epp.PageTable.query.PageQuery; +import com.cxyxiaomo.epp.PageTable.utils.FieldBuilder; +import com.cxyxiaomo.epp.PageTable.utils.FieldMapperBuilder; +import com.cxyxiaomo.epp.access.rpc.UserServiceFeign; +import com.cxyxiaomo.epp.access.service.AccessLogService; +import com.cxyxiaomo.epp.access.service.GateService; +import com.cxyxiaomo.epp.common.pojo.AccessLog; +import com.cxyxiaomo.epp.common.pojo.Gate; +import com.cxyxiaomo.epp.common.pojo.User; +import com.cxyxiaomo.epp.common.query.AccessLogQuery; +import com.cxyxiaomo.epp.common.response.Res; +import com.cxyxiaomo.epp.common.vo.AccessLogVO; +import com.cxyxiaomo.epp.common.vo.GateVO; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.text.SimpleDateFormat; +import java.util.*; + +@RestController +@RequestMapping("/access/access-log") +public class AccessLogController { + + @Resource + GateService gateService; + + @Resource + UserServiceFeign userService; + + @Resource + AccessLogService accessLogService; + + /** + * 进入进出记录(小程序端) + * + * @return + */ + @GetMapping("/miniprogram/enterGate") + @ResponseBody + public Res enterAccessLog(Integer userId, String gateId, String type/*'IN','OUT'*/) throws Exception { + if (Objects.isNull(type) || !("IN".equals(type) || "OUT".equals(type))) { + return Res.error("参数错误"); + } + + Gate gate = gateService.getGateById(Long.valueOf(gateId)); + User user = userService.getUserById(userId); + if (user == null || gate == null) { + return Res.error("参数错误"); + } + + AccessLog accessLog = new AccessLog(); + accessLog.setId(null); + accessLog.setType(type); + accessLog.setTime(new Date()); + accessLog.setUserId(user.getId()); + accessLog.setUserRealName(user.getRealname()); + accessLog.setGateId(gate.getId()); + + boolean b = accessLogService.addAccessLog(accessLog); + return Res.success(b); + } + + /** + * 获取进出记录列表 + * + * @return + */ + @GetMapping("/manage/getAccessLogList") + @ResponseBody + public Res getAccessLogList(PageQuery pageQuery, AccessLogQuery accessLogQuery) { + // 查询分页数据 + PageHelper.startPage(pageQuery.getPageIndex(), pageQuery.getPageSize()); + List accessLogList = accessLogService.getAccessLogList(accessLogQuery); + PageInfo accessLogPageInfo = new PageInfo<>(accessLogList); + List list = accessLogPageInfo.getList(); + List voList = AccessLogVO.convertFrom(list); + + // id列 字段名(区分大小写;以VO中的变量名为准) + // 新增、修改弹窗时,使用该列作为主键列进行操作 + String idFieldName = "id"; + + // 当前管理页面 + String pageName = "进出记录管理"; + + // 指定前端表格显示列 + JSONArray columns = FieldBuilder.create() + .add("timestamp", "timestamp", "打卡时间", "", + FieldType.DATETIME, SearchType.DATETIME_INTERVAL, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT, + FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME, + null, null, null, null + ) + .add("userId", "userId", "用户id", "", + FieldType.TEXT, SearchType.INPUT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT, + FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME, + null, null, null, null + ) + .add("userRealName", "userRealName", "用户真实姓名", "", + FieldType.TEXT, SearchType.INPUT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT, + FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME, + null, null, null, null + ) + .add("gateId", "gateId", "大门id", "", + FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT, + FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME, + null, null, null, null + ) + .add("gateId", "gateName", "大门名称", "", + FieldType.TEXT, SearchType.SELECT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT, + "大门", + null, null, null, null + ) + // .add("type", "typeStatus", "类型", true, + // FieldType.TEXT, SearchType.SELECT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT, + // FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME, + // "状态", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER, + // FieldRuleListBuilder.create(), + // "DPD @pick(['true', 'false'])" + // ) + .build(); + + // 指定需要翻译的字段 + List gateList = gateService.getGateList(new GateVO()); + HashMap gateMap = new HashMap(); + for (Gate gate : gateList) { + gateMap.put(gate.getId(), gate.getName()); + } + HashMap stateMap = new HashMap<>(2); + stateMap.put(true, "进入社区"); + stateMap.put(false, "离开社区"); + // build + JSONArray fieldMapper = FieldMapperBuilder.create() + .add("gateId", "gateName", gateMap) + .add("type", "typeStatus", stateMap) + .build(); + + // 拼装返回结果 + JSONObject map = new JSONObject(6); + map.put("total", accessLogPageInfo.getTotal()); + map.put("list", voList); + map.put("columns", columns); + map.put("fieldMapper", fieldMapper); + map.put("idFieldName", idFieldName); + map.put("pageName", pageName); + + // 返回结果 + return Res.success(map); + } + + /** + * 导出进出记录列表 + * + * @return + */ + @GetMapping("/manage/exportAccessLogList") + @ResponseBody + public Res exportAccessLogList(AccessLogQuery accessLogQuery) { + List accessLogList = accessLogService.getAccessLogList(accessLogQuery); + List accessLogVOList = AccessLogVO.convertFrom(accessLogList); + + // 当前时间 + Date now = Calendar.getInstance().getTime(); + SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss"); + String dateTime = format.format(now); + + HashMap map = new HashMap<>(); + map.put("list", accessLogVOList); + map.put("sheetName", "社区进出记录表-" + System.currentTimeMillis()); + map.put("fileName", "社区进出记录表_导出时间_" + dateTime); + + return Res.success(map); + } +} diff --git a/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/dao/AccessLogDao.java b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/dao/AccessLogDao.java new file mode 100644 index 0000000..b9fdc77 --- /dev/null +++ b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/dao/AccessLogDao.java @@ -0,0 +1,21 @@ +package com.cxyxiaomo.epp.access.dao; + +import com.cxyxiaomo.epp.common.pojo.AccessLog; +import com.cxyxiaomo.epp.common.query.AccessLogQuery; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Mapper +@Repository +public interface AccessLogDao { + + public boolean addAccessLog(AccessLog accessLog); + + public boolean updateAccessLog(AccessLog accessLog); + + public List getAccessLogList(AccessLogQuery accessLogQuery); + + public boolean deleteAccessLogById(Long gateId); +} diff --git a/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/service/AccessLogService.java b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/service/AccessLogService.java new file mode 100644 index 0000000..f9552c5 --- /dev/null +++ b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/service/AccessLogService.java @@ -0,0 +1,41 @@ +package com.cxyxiaomo.epp.access.service; + +import com.cxyxiaomo.epp.access.dao.AccessLogDao; +import com.cxyxiaomo.epp.common.pojo.AccessLog; +import com.cxyxiaomo.epp.common.query.AccessLogQuery; +import com.cxyxiaomo.epp.common.utils.SnowflakeManager; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; + +@Service +public class AccessLogService { + + @Resource + AccessLogDao accessLogDao; + + public List getAccessLogList(AccessLogQuery accessLogQuery) { + if (Objects.nonNull(accessLogQuery.getType()) && "".equals(accessLogQuery.getType())) { + accessLogQuery.setType(null); + } + return accessLogDao.getAccessLogList(accessLogQuery); + } + + public boolean addAccessLog(AccessLog accessLog) throws Exception { + // 创建日志编号 + SnowflakeManager snowflakeManager = new SnowflakeManager(1L, 1L); + long orderId = snowflakeManager.nextValue(); + accessLog.setId(orderId); + return accessLogDao.addAccessLog(accessLog); + } + + public boolean updateAccessLog(AccessLog accessLog) { + return accessLogDao.updateAccessLog(accessLog); + } + + public boolean deleteAccessLog(Long accessLogId) { + return accessLogDao.deleteAccessLogById(accessLogId); + } +} diff --git a/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/service/GateService.java b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/service/GateService.java index 0fdd73f..7279d9c 100644 --- a/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/service/GateService.java +++ b/backend/microservice-provider-access-8002/src/main/java/com/cxyxiaomo/epp/access/service/GateService.java @@ -28,7 +28,7 @@ public class GateService { } public boolean addGate(Gate gate) throws Exception { - // 创建订单编号 + // 创建大门编号 SnowflakeManager snowflakeManager = new SnowflakeManager(1L, 1L); long orderId = snowflakeManager.nextValue(); gate.setId(orderId); diff --git a/backend/microservice-provider-access-8002/src/main/resources/mybatis/mapper/AccessLogDao.xml b/backend/microservice-provider-access-8002/src/main/resources/mybatis/mapper/AccessLogDao.xml new file mode 100644 index 0000000..97a64a2 --- /dev/null +++ b/backend/microservice-provider-access-8002/src/main/resources/mybatis/mapper/AccessLogDao.xml @@ -0,0 +1,54 @@ + + + + + INSERT INTO access_log (id, time, user_id, user_real_name, gate_id, type) + VALUES (#{id}, #{time}, #{userId}, #{userRealName}, #{gateId}, #{type}) + + + + UPDATE access_log + + time = #{time}, + user_id = #{userId}, + user_real_name = #{userRealName}, + gate_id = #{gateId}, + type = #{type} + + WHERE id = #{id} + + + + + + DELETE + FROM access_log + WHERE id = #{id} + + diff --git a/backend/microservice-provider-access-8002/src/main/resources/mybatis/mapper/GateDao.xml b/backend/microservice-provider-access-8002/src/main/resources/mybatis/mapper/GateDao.xml index 66087b2..d0c908d 100644 --- a/backend/microservice-provider-access-8002/src/main/resources/mybatis/mapper/GateDao.xml +++ b/backend/microservice-provider-access-8002/src/main/resources/mybatis/mapper/GateDao.xml @@ -29,7 +29,7 @@ AND id = #{id} - AND name = #{name} + AND name LIKE concat('%',#{name,jdbcType=VARCHAR},'%') AND open = #{open} diff --git a/backend/microservice-provider-access-8002/src/main/resources/static/access/renderer.js b/backend/microservice-provider-access-8002/src/main/resources/static/access/renderer.js index 51c8576..d9a0272 100644 --- a/backend/microservice-provider-access-8002/src/main/resources/static/access/renderer.js +++ b/backend/microservice-provider-access-8002/src/main/resources/static/access/renderer.js @@ -68,7 +68,7 @@ function updateQRCode() { if (i % refreshTime == 0) { // scene 最长支支持 32 位,所以这里不传入时间戳 - let scene = encodeURIComponent(`guard&${window.currentGate.id}`); // &${Date.now()} + let scene = encodeURIComponent(`guard;${window.currentGate.id}`); // &${Date.now()} image.src = `${url}?page=${page}&scene=${scene}&envVersion=${envVersion}&width=${width}&autoColor=${autoColor}&isHyaline=${isHyaline}` console.log(image.src) refreshTimeCountDown.innerHTML = ` ` diff --git a/docs/ChatGPT/生成Mybatis xml SQL语句2.md b/docs/ChatGPT/生成Mybatis xml SQL语句2.md index 878397d..67ad4d4 100644 --- a/docs/ChatGPT/生成Mybatis xml SQL语句2.md +++ b/docs/ChatGPT/生成Mybatis xml SQL语句2.md @@ -1,23 +1,28 @@ -CREATE TABLE `gate` ( - `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '雪花id', - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '大门显示名称', - `open` tinyint(1) NOT NULL DEFAULT 1 COMMENT '大门是否开放 1为开放 2为关闭', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社区大门' ROW_FORMAT = DYNAMIC; +CREATE TABLE `access_log` ( + `id` bigint(20) NOT NULL COMMENT '雪花id', + `time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '进出时间', + `user_id` int(11) NOT NULL COMMENT '用户id', + `user_real_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户真实姓名', + `gate_id` bigint(20) NOT NULL COMMENT '大门id', + `type` enum('IN','OUT') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '类型(进门 OR 出门)' +) 创建该表的 add update getList deleteById 的 Mybatils xml片段 -(例如:) 实体类如下 -public class Gate implements Serializable { +public class AccessLog implements Serializable { private Long id; - private String name; - private Boolean open; + private Date time; + private Integer userId; + private String userRealName; + private Long gateId; + private String type; } 以下是一些要求 -parameterType="com.cxyxiaomo.epp.common.pojo.Gate" +parameterType="com.cxyxiaomo.epp.common.pojo.AccessLog" where 条件所引用的Java变量都需要先判断是否为null或空 输出应该为一个 ```code``` 包起来的代码片段 \ No newline at end of file diff --git a/frontend/src/api/access-log.js b/frontend/src/api/access-log.js new file mode 100644 index 0000000..4152259 --- /dev/null +++ b/frontend/src/api/access-log.js @@ -0,0 +1,41 @@ +import send_request from '../utils/send_request'; + +/** + * 获取进出记录列表 + * @returns + */ +export function getAccessLogList(params) { + // 深拷贝一份,避免 删除 timestamp 时页面上的输入框也清空了 + // 但是 Date 类型的对象无法拷贝,所以还是获取深拷贝之间的 + let paramsCopy = JSON.parse(JSON.stringify(params)) + delete paramsCopy.timestamp + if (Array.isArray(params.timestamp) && params.timestamp.length == 2) { + paramsCopy.startTime = params.timestamp[0]?.getTime() + paramsCopy.endTime = params.timestamp[1]?.getTime() + } + return send_request({ + url: '/access/access-log/manage/getAccessLogList', + method: 'GET', + params: paramsCopy, + }); +}; + +/** + * 导出进出记录列表 + * @returns + */ +export function exportAccessLogList(params) { + // 深拷贝一份,避免 删除 timestamp 时页面上的输入框也清空了 + // 但是 Date 类型的对象无法拷贝,所以还是获取深拷贝之间的 + let paramsCopy = JSON.parse(JSON.stringify(params)) + delete paramsCopy.timestamp + if (Array.isArray(params.timestamp) && params.timestamp.length == 2) { + paramsCopy.startTime = params.timestamp[0]?.getTime() + paramsCopy.endTime = params.timestamp[1]?.getTime() + } + return send_request({ + url: '/access/access-log/manage/exportAccessLogList', + method: 'GET', + params: paramsCopy, + }); +}; diff --git a/frontend/src/components/manage-list.vue b/frontend/src/components/manage-list.vue index d96bdc9..7729f58 100644 --- a/frontend/src/components/manage-list.vue +++ b/frontend/src/components/manage-list.vue @@ -487,7 +487,7 @@ const handleExport = async () => { // 如果选择仅导出满肚条件的数据,那么这里就填上查询参数 if (exportConfig.value.withFilter) { params = JSON.parse(JSON.stringify(query)) - // 去除分页参数 + // 去除分页参数 delete params["pageIndex"] delete params["pageSize"] } @@ -514,6 +514,17 @@ const handleExport = async () => { } console.log("dataList", dataList) + // 日期转换 + let timeField = tableFields.value.filter((field: any) => field.type == "time") + console.log("timeField", timeField) + for (let field of timeField) { + console.log("field.prop", field.prop) + dataList = dataList.map((row: any) => { + row[field.prop] = new Date(row[field.prop] + 8 * 3600 * 1000).toISOString().replace('T', ' ').substring(0, 19) + return row + }) + } + // 所有列的 field let fieldNameList = exportFields.map((f: any) => f.field) fieldNameList.unshift(idFieldName) diff --git a/frontend/src/views/access-log.vue b/frontend/src/views/access-log.vue index a864de2..96a346c 100644 --- a/frontend/src/views/access-log.vue +++ b/frontend/src/views/access-log.vue @@ -1,11 +1,11 @@ diff --git a/weixin-miniprogram/pages/index/index.js b/weixin-miniprogram/pages/index/index.js index d119a91..21894f0 100644 --- a/weixin-miniprogram/pages/index/index.js +++ b/weixin-miniprogram/pages/index/index.js @@ -49,7 +49,7 @@ Page({ if (options && options.scene) { // 扫门禁的小程序码 let scene = options.scene - if (scene.startsWith("guard%")) { // scene.split('%')[0] == "guard" + if (scene.startsWith("guard")) { options.scene = null // 清掉参数 避免重复触发 wx.navigateTo({ url: "/pages/scan/entrance?scene=" + scene diff --git a/weixin-miniprogram/pages/scan/entrance.js b/weixin-miniprogram/pages/scan/entrance.js index 3d623c1..93867f0 100644 --- a/weixin-miniprogram/pages/scan/entrance.js +++ b/weixin-miniprogram/pages/scan/entrance.js @@ -25,19 +25,22 @@ Page({ * 生命周期函数--监听页面加载 */ onLoad(options) { - console.log(options) - let scene = options.scene - if (!scene) { - wx.navigateBack() - return - } - scene = decodeURIComponent(scene) // %26 == & - if (scene.indexOf('&') == -1) { - wx.navigateBack() + console.log("entrance -> options", typeof (options), options) + let scene = options.scene ? decodeURIComponent(options.scene) : undefined // %3B == ; %26 == & + console.log("scene", options.scene, scene) + if (!scene || scene.indexOf(';') == -1) { + wx.showModal({ + title: '出错啦', + content: '参数不正确' + JSON.stringify(options), + showCancel: false, + complete: (res) => { + wx.navigateBack() + } + }) return } - let gateId = scene.split('&')[1] + let gateId = scene.split(';')[1] this.setData({ gateId: gateId, }); @@ -109,6 +112,13 @@ Page({ })(); }, + enterGate: function () { + (async () => { + let enterGate = await gateService.enterGate(this.data.gateId, "IN") + console.log("enterGate", enterGate) + })(); + }, + navigateBack: function () { wx.navigateBack() } diff --git a/weixin-miniprogram/services/gate.js b/weixin-miniprogram/services/gate.js index 76e5c16..8e8d326 100644 --- a/weixin-miniprogram/services/gate.js +++ b/weixin-miniprogram/services/gate.js @@ -13,3 +13,18 @@ export function getGateDetail(id) { } }) } + +/** 进入大门 */ +export function enterGate(gateId, type) { + let userInfo = wx.getStorageSync("userInfo") + console.log("userId, gateId, type", userInfo.id, gateId, type) + return send_request({ + url: '/access/access-log/miniprogram/enterGate', + method: "GET", + data: { + userId: userInfo.id, + gateId, + type + } + }) +} diff --git a/weixin-miniprogram/utils/scanQRCode.js b/weixin-miniprogram/utils/scanQRCode.js index 9637fa7..9b7345f 100644 --- a/weixin-miniprogram/utils/scanQRCode.js +++ b/weixin-miniprogram/utils/scanQRCode.js @@ -5,12 +5,14 @@ function scanQRCode(wx) { success(res) { console.log(res) if (res.scanType == "WX_CODE" && res.path) { + // console.log("res.path", res.path) + // res.path pages/index/index?scene=guard;1758617522619420679 let searchParams = res.path.split('?'); - if (searchParams.length > 1 && searchParams[1].startsWith('scene=guard')) { - // let scene = searchParams[1].substring(searchParams[1].indexOf('=')) - console.log("searchParams", searchParams) + let params = searchParams[1] + console.log("searchParams", searchParams, "params", params) + if (params && params.startsWith('scene=guard')) { wx.navigateTo({ - url: "/pages/scan/entrance?" + searchParams[1] + url: "/pages/scan/entrance?" + params }) return }