Commit fd43edc5fa5fe34aea96d3d6ffc7ef7e3476970b
1 parent
c752417d
feat(*): 开发debug接口
- 开发debug接口
Showing
7 changed files
with
155 additions
and
9 deletions
fw-hermes-common/src/main/java/cn/fw/hermes/common/constant/Constant.java
fw-hermes-domain/src/main/java/cn/fw/hermes/domain/db/Hermes.java
... | ... | @@ -50,6 +50,10 @@ public class Hermes extends BaseAuditableTimeEntity<Hermes, Long> { |
50 | 50 | */ |
51 | 51 | private AccountStateEnum state; |
52 | 52 | /** |
53 | + * 信鸽设备token | |
54 | + */ | |
55 | + private String xgToken; | |
56 | + /** | |
53 | 57 | * 创建日期 |
54 | 58 | */ |
55 | 59 | @JsonDeserialize(using = LocalDateTimeSerializerProcessor.LocalDateDeserializer.class) | ... | ... |
fw-hermes-server/src/main/kotlin/cn/fw/hermes/controller/app/XgController.kt
0 → 100644
1 | +package cn.fw.hermes.controller.app | |
2 | + | |
3 | +import cn.fw.common.web.annotation.ControllerMethod | |
4 | +import cn.fw.common.web.util.ResultBuilder | |
5 | +import cn.fw.data.base.domain.common.Message | |
6 | +import cn.fw.hermes.domain.enums.AccountTypeEnum | |
7 | +import cn.fw.hermes.service.biz.XgPushBizService | |
8 | +import cn.fw.security.auth.client.annotation.Authorization | |
9 | +import cn.fw.security.auth.client.annotation.IgnoreAuth | |
10 | +import cn.fw.security.auth.client.enums.AuthType | |
11 | +import org.springframework.validation.annotation.Validated | |
12 | +import org.springframework.web.bind.annotation.PostMapping | |
13 | +import org.springframework.web.bind.annotation.RequestMapping | |
14 | +import org.springframework.web.bind.annotation.RequestParam | |
15 | +import org.springframework.web.bind.annotation.RestController | |
16 | + | |
17 | +/** | |
18 | + * 信鸽相关控制器 | |
19 | + * | |
20 | + * @author : kurisu | |
21 | + * @version : 1.0 | |
22 | + * @desc : 信鸽相关控制器 | |
23 | + * @date : 2024-01-05 18:08 | |
24 | + */ | |
25 | +@Validated | |
26 | +@RestController | |
27 | +@RequestMapping("/app/xinge") | |
28 | +@Authorization(AuthType.APP) | |
29 | +class XgController(private val xgPushBizService: XgPushBizService) { | |
30 | + | |
31 | + @IgnoreAuth | |
32 | + @ControllerMethod("绑定信鸽token") | |
33 | + @PostMapping("/bind") | |
34 | + fun bindToken(@RequestParam("userId") userId: Long?, @RequestParam("xgToken") xgToken: String): Message<Void> { | |
35 | + xgPushBizService.saveUserToken(userId, AccountTypeEnum.B_USER, xgToken) | |
36 | + return ResultBuilder.success() | |
37 | + } | |
38 | +} | ... | ... |
fw-hermes-server/src/main/kotlin/cn/fw/hermes/controller/common/XinGeDebugController.kt
... | ... | @@ -4,6 +4,7 @@ package cn.fw.hermes.controller.common |
4 | 4 | import cn.fw.common.web.annotation.ControllerMethod |
5 | 5 | import cn.fw.common.web.util.ResultBuilder.success |
6 | 6 | import cn.fw.data.base.domain.common.Message |
7 | +import cn.fw.hermes.domain.enums.AccountTypeEnum | |
7 | 8 | import cn.fw.hermes.domain.xinge.XinGeProfile |
8 | 9 | import cn.fw.hermes.service.biz.XgPushBizService |
9 | 10 | import cn.fw.hermes.service.property.XinGeProperty |
... | ... | @@ -13,6 +14,7 @@ import org.springframework.validation.annotation.Validated |
13 | 14 | import org.springframework.web.bind.annotation.GetMapping |
14 | 15 | import org.springframework.web.bind.annotation.RequestMapping |
15 | 16 | import org.springframework.web.bind.annotation.RestController |
17 | +import javax.validation.constraints.NotNull | |
16 | 18 | |
17 | 19 | /** |
18 | 20 | * 信鸽debug类 |
... | ... | @@ -29,8 +31,8 @@ import org.springframework.web.bind.annotation.RestController |
29 | 31 | class XinGeDebugController(private val xinGeProperty: XinGeProperty, private val xgPushBizService: XgPushBizService) { |
30 | 32 | @ControllerMethod("信鸽推送测试消息") |
31 | 33 | @GetMapping("/send/msg") |
32 | - fun sendMsg(): Message<Void> { | |
33 | - xgPushBizService.sendData() | |
34 | + fun sendMsg(@NotNull(message = "用户id不能为空") userId: Long?): Message<Void> { | |
35 | + userId?.let { xgPushBizService.sendData(it, AccountTypeEnum.B_USER) } | |
34 | 36 | return success() |
35 | 37 | } |
36 | 38 | ... | ... |
fw-hermes-service/src/main/java/cn/fw/hermes/service/data/HermesService.java
fw-hermes-service/src/main/java/cn/fw/hermes/service/data/impl/HermesServiceImpl.java
... | ... | @@ -30,14 +30,14 @@ public class HermesServiceImpl extends ServiceImpl<HermesMapper, Hermes> impleme |
30 | 30 | @Override |
31 | 31 | public Hermes queryByUserId(Long userId, AccountTypeEnum type) { |
32 | 32 | return getOne(Wrappers.<Hermes>lambdaQuery() |
33 | - .eq(Hermes::getUserId, userId) | |
34 | - .eq(Hermes::getAccountType, type) | |
35 | - , Boolean.FALSE); | |
33 | + .eq(Hermes::getUserId, userId) | |
34 | + .eq(Hermes::getAccountType, type) | |
35 | + , Boolean.FALSE); | |
36 | 36 | } |
37 | 37 | |
38 | 38 | @Transactional(rollbackFor = Exception.class) |
39 | 39 | @Override |
40 | - @CacheEvict(cacheNames = Constant.ACCOUNT_CACHE_KEY, key = "#dto.userId", condition = "#dto.id != null") | |
40 | + @CacheEvict(cacheNames = Constant.ACCOUNT_CACHE_KEY, key = "#dto.userId+':'+#dto.accountType.name()", condition = "#dto.id != null") | |
41 | 41 | public void saveByDto(HermesDTO dto) { |
42 | 42 | Hermes db = new Hermes(); |
43 | 43 | BeanUtils.copyProperties(dto, db); | ... | ... |
fw-hermes-service/src/main/kotlin/cn/fw/hermes/service/biz/XgPushBizService.kt
1 | 1 | package cn.fw.hermes.service.biz |
2 | 2 | |
3 | +import cn.fw.common.businessvalidator.Validator.BV | |
4 | +import cn.fw.common.util.logInfo | |
5 | +import cn.fw.hermes.common.constant.Constant | |
6 | +import cn.fw.hermes.domain.db.Hermes | |
7 | +import cn.fw.hermes.domain.enums.AccountTypeEnum | |
8 | +import cn.fw.hermes.service.data.HermesService | |
9 | +import com.baomidou.mybatisplus.core.toolkit.Wrappers | |
3 | 10 | import com.tencent.xinge.XingeApp |
4 | 11 | import com.tencent.xinge.bean.AudienceType |
5 | 12 | import com.tencent.xinge.bean.Message |
6 | 13 | import com.tencent.xinge.bean.MessageAndroid |
7 | 14 | import com.tencent.xinge.bean.MessageType |
15 | +import com.tencent.xinge.device.account.AccountBindOperatorType | |
16 | +import com.tencent.xinge.device.account.AccountBindRequest | |
17 | +import com.tencent.xinge.device.account.AccountTypePair | |
18 | +import com.tencent.xinge.device.account.TokenAccountsPair | |
8 | 19 | import com.tencent.xinge.push.app.PushAppRequest |
20 | +import kotlinx.coroutines.CoroutineScope | |
21 | +import kotlinx.coroutines.Dispatchers | |
22 | +import kotlinx.coroutines.launch | |
23 | +import org.springframework.beans.factory.annotation.Value | |
24 | +import org.springframework.cloud.context.config.annotation.RefreshScope | |
25 | +import org.springframework.data.redis.core.StringRedisTemplate | |
9 | 26 | import org.springframework.stereotype.Service |
27 | +import org.springframework.transaction.annotation.Transactional | |
10 | 28 | import java.util.* |
11 | 29 | |
12 | 30 | |
... | ... | @@ -19,10 +37,49 @@ import java.util.* |
19 | 37 | * @date : 2024-01-04 15:54 |
20 | 38 | */ |
21 | 39 | @Service |
22 | -class XgPushBizService(private val xingeApp: XingeApp) { | |
40 | +@RefreshScope | |
41 | +class XgPushBizService( | |
42 | + @Value("\${spring.cache.custom.global-prefix}:xg:token") | |
43 | + private val keyPrefix: String, | |
44 | + private val xingeApp: XingeApp, | |
45 | + private val hermesService: HermesService, | |
46 | + private val stringRedisTemplate: StringRedisTemplate | |
47 | +) { | |
23 | 48 | |
49 | + /** | |
50 | + * 储存和更新用户腾讯信鸽设备的token | |
51 | + */ | |
52 | + @Transactional(rollbackFor = [Exception::class]) | |
53 | + fun saveUserToken(userId: Long?, accountType: AccountTypeEnum, xgToken: String) { | |
54 | + BV.notNull(userId) { "用户信息不存在" } | |
55 | + userId?.let { | |
56 | + val hermes = hermesService.queryByUserId(it, accountType) | |
57 | + hermes?.run { | |
58 | + val cacheKey = "${keyPrefix}:${accountType.name}" | |
59 | + val hashOps = stringRedisTemplate.boundHashOps<String, String>(cacheKey) | |
60 | + val clearUserIds = blankingToken(it, accountType, xgToken) | |
61 | + CoroutineScope(Dispatchers.IO).launch { | |
62 | + clearTokenAccount(xgToken, identifier) | |
63 | + } | |
64 | + val her = Hermes() | |
65 | + her.id = id | |
66 | + her.xgToken = xgToken | |
67 | + if (her.updateById()) { | |
68 | + hashOps.put(it.toString(), xgToken) | |
69 | + } | |
70 | + if (clearUserIds.isNotEmpty()) { | |
71 | + val clearUserList = clearUserIds.map { userId -> userId.toString() }.toTypedArray() | |
72 | + hashOps.delete(*clearUserList) | |
73 | + } | |
74 | + } | |
75 | + } | |
76 | + } | |
24 | 77 | |
25 | - fun sendData() { | |
78 | + fun sendData(userId: Long, accountType: AccountTypeEnum) { | |
79 | + val xgToken = getUserToken(userId, accountType) | |
80 | + BV.isFalse(Constant.inValidToken == xgToken) { | |
81 | + "用户设备未找到" | |
82 | + } | |
26 | 83 | val pushAppRequest = PushAppRequest() |
27 | 84 | pushAppRequest.audience_type = AudienceType.token |
28 | 85 | pushAppRequest.message_type = MessageType.notify |
... | ... | @@ -39,7 +96,47 @@ class XgPushBizService(private val xingeApp: XingeApp) { |
39 | 96 | messageAndroid.setnCategory("CATEGORY_REMINDER") |
40 | 97 | messageAndroid.ring_raw = "xg_ring" |
41 | 98 | message.android = messageAndroid |
42 | - pushAppRequest.token_list = arrayListOf("02b9c9dc7b4c2c392f08fd793397e4f50571") | |
99 | + pushAppRequest.token_list = arrayListOf(xgToken) | |
43 | 100 | this.xingeApp.pushApp(pushAppRequest) |
44 | 101 | } |
102 | + | |
103 | + private fun getUserToken(userId: Long, accountType: AccountTypeEnum): String { | |
104 | + val cacheKey = "${keyPrefix}:${accountType.name}" | |
105 | + val hashOps = stringRedisTemplate.boundHashOps<String, String>(cacheKey) | |
106 | + val xToken = hashOps.get(userId.toString()) | |
107 | + return xToken ?: hermesService.queryByUserId(userId, accountType)?.xgToken ?: Constant.inValidToken | |
108 | + } | |
109 | + | |
110 | + private fun clearTokenAccount(token: String, account: String) { | |
111 | + val request = AccountBindRequest() | |
112 | + request.operatorType = AccountBindOperatorType.BatchCoverAccount | |
113 | + val accountTypePair = AccountTypePair() | |
114 | + accountTypePair.account = account | |
115 | + | |
116 | + val accountTypePairs = arrayListOf(accountTypePair) | |
117 | + request.accountList = accountTypePairs | |
118 | + | |
119 | + val tokenAccountsPair = TokenAccountsPair() | |
120 | + tokenAccountsPair.accountList = accountTypePairs | |
121 | + tokenAccountsPair.token = token | |
122 | + | |
123 | + request.tokenAccounts = arrayListOf(tokenAccountsPair) | |
124 | + val bindRes = this.xingeApp.accountBind(request) | |
125 | + logInfo("给[{}]绑定账号[{}], 结果: {}", token, account, bindRes) | |
126 | + } | |
127 | + | |
128 | + private fun blankingToken(userId: Long, accountType: AccountTypeEnum, xgToken: String): List<Long> { | |
129 | + val list = hermesService.list( | |
130 | + Wrappers.lambdaQuery<Hermes>() | |
131 | + .eq(Hermes::getXgToken, xgToken) | |
132 | + .eq(Hermes::getAccountType, accountType) | |
133 | + .ne(Hermes::getUserId, userId) | |
134 | + ) | |
135 | + if (list.isNullOrEmpty()) { | |
136 | + return listOf() | |
137 | + } | |
138 | + list.forEach { it.xgToken = Constant.inValidToken } | |
139 | + hermesService.updateBatchById(list) | |
140 | + return list.map(Hermes::getUserId) | |
141 | + } | |
45 | 142 | } | ... | ... |