| | |
| | | @Transactional |
| | | public Map<String, Object> createDevelopmentSession(long talentId) { |
| | | List<Map<String, Object>> talents = rows(""" |
| | | select id, openid |
| | | select id, openid, status |
| | | from talent_user |
| | | where id = ? and deleted = 0 and status = 1 |
| | | where id = ? and deleted = 0 |
| | | limit 1 for update |
| | | """, talentId); |
| | | if (talents.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "开发测试人才账号不存在或不可用"); |
| | | if (talents.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "开发测试人才账号不存在"); |
| | | if (number(talents.get(0).get("status")) != 1) { |
| | | throw new BusinessException(ErrorCode.FORBIDDEN, "持卡人被停用"); |
| | | } |
| | | Object openId = talents.get(0).get("openid"); |
| | | if (openId == null || String.valueOf(openId).isBlank()) { |
| | | throw new BusinessException(ErrorCode.CONFLICT, "开发测试人才账号未配置微信标识"); |
| | |
| | | |
| | | private Map<String, Object> establishSession(String openId, String mobile) { |
| | | List<Map<String, Object>> talents = rows(""" |
| | | select id, openid |
| | | select id, openid, status |
| | | from talent_user |
| | | where mobile = ? and deleted = 0 and status = 1 |
| | | where mobile = ? and deleted = 0 |
| | | limit 1 for update |
| | | """, mobile); |
| | | if (talents.isEmpty()) throw new BusinessException(ErrorCode.FORBIDDEN, "当前手机号未录入人才服务名单,请联系管理员"); |
| | | if (talents.isEmpty()) return issueSession(registerVisitor(openId, mobile)); |
| | | Map<String, Object> talent = talents.get(0); |
| | | long talentId = number(talent.get("id")); |
| | | List<Map<String, Object>> binding = rows("select id from talent_user where openid = ? and deleted = 0 limit 1 for update", openId); |
| | | if (!binding.isEmpty() && number(binding.get(0).get("id")) != talentId) { |
| | | throw new BusinessException(ErrorCode.CONFLICT, "当前微信已绑定其他人才账号,请联系管理员"); |
| | | if (number(talent.get("status")) != 1) { |
| | | throw new BusinessException(ErrorCode.FORBIDDEN, "持卡人被停用"); |
| | | } |
| | | long talentId = number(talent.get("id")); |
| | | List<Map<String, Object>> binding = rows(""" |
| | | select t.id |
| | | from talent_user t |
| | | where t.openid = ? and t.deleted = 0 |
| | | limit 1 for update |
| | | """, openId); |
| | | if (!binding.isEmpty() && number(binding.get(0).get("id")) != talentId) { |
| | | long previousTalentId = number(binding.get(0).get("id")); |
| | | jdbc.update("update talent_session set revoked_at = coalesce(revoked_at, now()) where talent_id = ? and revoked_at is null", previousTalentId); |
| | | } |
| | | // uk_openid 是唯一索引:已软删/停用的历史账号照样占着这个 openid,不先摘掉就会撞唯一键(接口报「服务器内部错误」)。 |
| | | releaseOpenId(openId, talentId); |
| | | jdbc.update("update talent_user set openid = ? where id = ?", openId, talentId); |
| | | return issueSession(talentId); |
| | | } |
| | | |
| | | /** 把 openid 从除 keepTalentId 之外的所有行上摘掉(含软删、停用的历史账号)。 */ |
| | | private void releaseOpenId(String openId, long keepTalentId) { |
| | | jdbc.update("update talent_user set openid = null where openid = ? and id <> ?", openId, keepTalentId); |
| | | } |
| | | |
| | | private long registerVisitor(String openId, String mobile) { |
| | | List<Map<String, Object>> bindings = rows(""" |
| | | select id |
| | | from talent_user |
| | | where openid = ? and deleted = 0 and status = 1 |
| | | limit 1 for update |
| | | """, openId); |
| | | if (!bindings.isEmpty()) { |
| | | long talentId = number(bindings.get(0).get("id")); |
| | | jdbc.update("update talent_user set mobile = ? where id = ?", mobile, talentId); |
| | | return talentId; |
| | | } |
| | | // 没有可用的绑定时要把历史占用清掉,否则下面这条 insert 会撞 uk_openid。 |
| | | jdbc.update("update talent_user set openid = null where openid = ?", openId); |
| | | jdbc.update(""" |
| | | insert into talent_user(openid, name, mobile, talent_level, source_area_type, status) |
| | | values (?, '普通游客', ?, '普通游客', 'LOCAL', 1) |
| | | """, openId, mobile); |
| | | Long talentId = jdbc.queryForObject("select last_insert_id()", Long.class); |
| | | if (talentId == null) throw new BusinessException(ErrorCode.INTERNAL_ERROR, "普通游客注册失败"); |
| | | return talentId; |
| | | } |
| | | |
| | | private Map<String, Object> issueSession(long talentId) { |
| | | jdbc.update("update talent_session set revoked_at = now() where talent_id = ? and revoked_at is null", talentId); |
| | | |