Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gxpt_ht
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pseer
gxpt_ht
Commits
5bbff7b3
Commit
5bbff7b3
authored
Oct 11, 2024
by
吕明尚
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改验券幂等
parent
a35eee80
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
94 additions
and
88 deletions
+94
-88
pom.xml
share-common/pom.xml
+0
-6
RedisLockUtil.java
...ommon/src/main/java/share/common/utils/RedisLockUtil.java
+75
-0
RepeatSubmit.java
...on/src/main/java/share/common/utils/aop/RepeatSubmit.java
+0
-14
RepeatSubmitAspect.java
.../main/java/share/common/utils/aop/RepeatSubmitAspect.java
+0
-61
QPServiceImpl.java
...rc/main/java/share/system/service/impl/QPServiceImpl.java
+11
-5
TiktokServiceImpl.java
...ain/java/share/system/service/impl/TiktokServiceImpl.java
+8
-2
No files found.
share-common/pom.xml
View file @
5bbff7b3
...
...
@@ -177,11 +177,6 @@
<version>
1.4.9
</version>
</dependency>
<dependency>
<groupId>
com.google.guava
</groupId>
<artifactId>
guava
</artifactId>
<version>
21.0
</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
share-common/src/main/java/share/common/utils/RedisLockUtil.java
0 → 100644
View file @
5bbff7b3
package
share
.
common
.
utils
;
import
org.springframework.data.redis.core.RedisCallback
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.Objects
;
/**
* @ClassName RedisLockUtil
* @Description 使用redis做锁
* @Author Wangyujie
* @Version V1.1.0
*/
@Component
public
class
RedisLockUtil
{
@Resource
RedisTemplate
<
String
,
Object
>
redisTemplate
;
/**
* 获取锁Key
*
* @param prefix 前缀
* @param name 名称
* @return
*/
public
static
String
getFullKey
(
String
prefix
,
String
name
)
{
return
prefix
+
"_"
+
name
;
}
/**
* 获取锁,true 则得到锁,false 已被锁定
*
* @param lockName 锁名称
* @param lockExoire 锁时间毫秒
* @return
*/
public
Boolean
getLock
(
String
lockName
,
Integer
lockExoire
)
{
return
(
Boolean
)
redisTemplate
.
execute
((
RedisCallback
<?>)
connection
->
{
// 获取时间毫秒值
long
expireAt
=
System
.
currentTimeMillis
()
+
lockExoire
+
1
;
// 获取锁
Boolean
acquire
=
connection
.
setNX
(
lockName
.
getBytes
(),
String
.
valueOf
(
expireAt
).
getBytes
());
if
(
acquire
)
{
return
true
;
}
else
{
byte
[]
bytes
=
connection
.
get
(
lockName
.
getBytes
());
// 非空判断
if
(
Objects
.
nonNull
(
bytes
)
&&
bytes
.
length
>
0
)
{
long
expireTime
=
Long
.
parseLong
(
new
String
(
bytes
));
// 如果锁已经过期
if
(
expireTime
<
System
.
currentTimeMillis
())
{
// 重新加锁,防止死锁
byte
[]
set
=
connection
.
getSet
(
lockName
.
getBytes
(),
String
.
valueOf
(
System
.
currentTimeMillis
()
+
lockExoire
+
1
).
getBytes
());
return
Long
.
parseLong
(
new
String
(
set
))
<
System
.
currentTimeMillis
();
}
}
}
return
false
;
});
}
/**
* 删除锁
*
* @param lockName
*/
public
void
delLock
(
String
lockName
)
{
redisTemplate
.
delete
(
lockName
);
}
}
share-common/src/main/java/share/common/utils/aop/RepeatSubmit.java
deleted
100644 → 0
View file @
a35eee80
package
share
.
common
.
utils
.
aop
;
import
java.lang.annotation.*
;
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
@Inherited
public
@interface
RepeatSubmit
{
String
key
()
default
""
;
}
share-common/src/main/java/share/common/utils/aop/RepeatSubmitAspect.java
deleted
100644 → 0
View file @
a35eee80
package
share
.
common
.
utils
.
aop
;
import
com.google.common.cache.Cache
;
import
com.google.common.cache.CacheBuilder
;
import
org.apache.commons.lang3.StringUtils
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.springframework.stereotype.Component
;
import
java.lang.reflect.Method
;
import
java.util.concurrent.TimeUnit
;
@Aspect
@Component
public
class
RepeatSubmitAspect
{
private
static
final
Cache
<
String
,
Object
>
CACHES
=
CacheBuilder
.
newBuilder
()
// 最大缓存 设置为1000个
.
maximumSize
(
1000
)
// 设置写缓存后1s过期
.
expireAfterWrite
(
1
,
TimeUnit
.
SECONDS
)
.
build
();
@Around
(
"execution(public * *(..)) && @annotation(share.common.utils.aop.RepeatSubmit))"
)
public
Object
interceptor
(
ProceedingJoinPoint
pjp
)
{
MethodSignature
signature
=
(
MethodSignature
)
pjp
.
getSignature
();
Method
method
=
signature
.
getMethod
();
RepeatSubmit
repeatSubmit
=
method
.
getAnnotation
(
RepeatSubmit
.
class
);
String
key
=
getKey
(
repeatSubmit
.
key
(),
pjp
.
getArgs
());
if
(
StringUtils
.
isNotBlank
(
key
))
{
if
(
CACHES
.
getIfPresent
(
key
)
!=
null
)
{
throw
new
RuntimeException
(
"请勿重复请求"
);
}
// 如果是第一次请求,就将key 当前对象压入缓存中
CACHES
.
put
(
key
,
key
);
}
try
{
return
pjp
.
proceed
();
}
catch
(
Throwable
throwable
)
{
throw
new
RuntimeException
(
"服务器异常!"
);
}
}
/**
* key 的生成策略
*
* @param keyExpress 表达式
* @param args 参数
* @return 生成的key
*/
private
String
getKey
(
String
keyExpress
,
Object
[]
args
)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
keyExpress
=
keyExpress
.
replace
(
"arg["
+
i
+
"]"
,
args
[
i
].
toString
());
}
return
keyExpress
;
}
}
share-system/src/main/java/share/system/service/impl/QPServiceImpl.java
View file @
5bbff7b3
...
...
@@ -32,7 +32,7 @@ import share.common.core.redis.RedisUtil;
import
share.common.enums.*
;
import
share.common.exception.base.BaseException
;
import
share.common.utils.DateUtils
;
import
share.common.utils.
aop.RepeatSubmit
;
import
share.common.utils.
RedisLockUtil
;
import
share.system.domain.SConsumer
;
import
share.system.domain.SConsumerCoupon
;
import
share.system.domain.SCoupon
;
...
...
@@ -78,6 +78,9 @@ public class QPServiceImpl implements QPService {
private
RedisUtil
redisUtil
;
@Autowired
private
RedisLockUtil
redisLockUtil
;
@Autowired
private
ISStoreService
storeService
;
//默认门槛时长
...
...
@@ -101,13 +104,14 @@ public class QPServiceImpl implements QPService {
* 用户验卷接口
*/
@Override
@RepeatSubmit
(
key
=
"美团验卷"
)
public
String
consumeByUser
(
String
code
,
String
storeId
,
String
status
)
throws
Exception
{
//获取用户信息
SConsumer
user
=
FrontTokenComponent
.
getWxSConsumerEntry
();
if
(
ObjectUtil
.
isNull
(
user
))
{
throw
new
BaseException
(
"您的登录已过期,请先登录"
);
}
Boolean
lock
=
redisLockUtil
.
getLock
(
String
.
valueOf
(
user
.
getId
()),
1000
);
if
(
lock
)
{
LambdaQueryWrapper
<
SStore
>
sStoreLambdaQueryWrapper
=
new
LambdaQueryWrapper
<>();
sStoreLambdaQueryWrapper
.
eq
(
SStore:
:
getId
,
storeId
);
SStore
sStore
=
storeService
.
getOne
(
sStoreLambdaQueryWrapper
);
...
...
@@ -117,8 +121,6 @@ public class QPServiceImpl implements QPService {
if
(
StringUtils
.
isEmpty
(
sStore
.
getOpenShopUuid
()))
{
throw
new
Exception
(
"门店未授权,请联系客服"
);
}
//验券准备
TuangouReceiptPrepareResponseEntity
prepare
=
prepare
(
code
.
trim
(),
sStore
.
getOpenShopUuid
(),
status
);
//查询领取记录表
LambdaQueryWrapper
<
SConsumerCoupon
>
queryWrapper
=
new
LambdaQueryWrapper
<>();
queryWrapper
.
eq
(
SConsumerCoupon:
:
getCouponCode
,
code
);
...
...
@@ -128,6 +130,8 @@ public class QPServiceImpl implements QPService {
if
(
ObjectUtils
.
isNotEmpty
(
unUsedCoupon
))
{
throw
new
Exception
(
"该券码已被使用"
);
}
//验券准备
TuangouReceiptPrepareResponseEntity
prepare
=
prepare
(
code
.
trim
(),
sStore
.
getOpenShopUuid
(),
status
);
//根据优惠卷名称查询优惠劵配置 查询list,取第一个
SConsumerCoupon
sConsumerCoupon
=
new
SConsumerCoupon
();
sConsumerCoupon
.
setConsumerId
(
user
.
getId
());
...
...
@@ -208,9 +212,11 @@ public class QPServiceImpl implements QPService {
}
isConsumerCouponService
.
insertSConsumerCoupon
(
sConsumerCoupon
);
//核销美团券
//
qpService.consume(code.trim(), 1, sStore.getOpenShopUuid(), status);
qpService
.
consume
(
code
.
trim
(),
1
,
sStore
.
getOpenShopUuid
(),
status
);
return
"验劵成功"
;
}
throw
new
RuntimeException
(
"验劵失败"
);
}
@Override
public
List
<
TuangouReceiptReverseConsumeResponseEntity
>
reverseconsumeByUser
(
Long
id
)
{
...
...
share-system/src/main/java/share/system/service/impl/TiktokServiceImpl.java
View file @
5bbff7b3
...
...
@@ -20,7 +20,7 @@ import org.springframework.util.CollectionUtils;
import
share.common.core.redis.RedisUtil
;
import
share.common.enums.*
;
import
share.common.exception.base.BaseException
;
import
share.common.utils.
aop.RepeatSubmit
;
import
share.common.utils.
RedisLockUtil
;
import
share.system.domain.SConsumer
;
import
share.system.domain.SConsumerCoupon
;
import
share.system.domain.SCoupon
;
...
...
@@ -55,6 +55,9 @@ public class TiktokServiceImpl implements TiktokService {
private
RedisUtil
redisUtil
;
@Autowired
private
RedisLockUtil
redisLockUtil
;
@Autowired
private
ISStoreService
storeService
;
@Autowired
...
...
@@ -352,12 +355,13 @@ public class TiktokServiceImpl implements TiktokService {
}
@Override
@RepeatSubmit
(
key
=
"抖音验卷"
)
public
String
consumeByUser
(
String
code
,
String
storeId
)
throws
Exception
{
SConsumer
user
=
FrontTokenComponent
.
getWxSConsumerEntry
();
if
(
ObjectUtil
.
isNull
(
user
))
{
throw
new
BaseException
(
"您的登录已过期,请先登录"
);
}
Boolean
lock
=
redisLockUtil
.
getLock
(
String
.
valueOf
(
user
.
getId
()),
1000
);
if
(
lock
)
{
LambdaQueryWrapper
<
SStore
>
sStoreLambdaQueryWrapper
=
new
LambdaQueryWrapper
<>();
sStoreLambdaQueryWrapper
.
eq
(
SStore:
:
getId
,
storeId
);
SStore
sStore
=
storeService
.
getOne
(
sStoreLambdaQueryWrapper
);
...
...
@@ -482,6 +486,8 @@ public class TiktokServiceImpl implements TiktokService {
}
return
"验卷成功"
;
}
throw
new
RuntimeException
(
"验劵失败"
);
}
@Override
public
List
<
TiktokPoi
>
poiList
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment