WriteOffCouponPropertyUserCmd.java
11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
package com.java110.acct.cmd.couponProperty;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.annotation.Java110Transactional;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.doc.annotation.*;
import com.java110.dto.coupon.CouponPropertyUserDto;
import com.java110.dto.coupon.CouponPropertyUserDetailDto;
import com.java110.dto.user.UserDto;
import com.java110.intf.acct.ICouponPropertyUserDetailV1InnerServiceSMO;
import com.java110.intf.acct.ICouponPropertyUserV1InnerServiceSMO;
import com.java110.intf.user.IUserV1InnerServiceSMO;
import com.java110.po.coupon.CouponPropertyUserPo;
import com.java110.po.coupon.CouponPropertyUserDetailPo;
import com.java110.utils.cache.CommonCache;
import com.java110.utils.exception.CmdException;
import com.java110.utils.lock.DistributedLock;
import com.java110.utils.util.Assert;
import com.java110.utils.util.StringUtil;
import com.java110.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import java.text.ParseException;
import java.util.List;
@Java110CmdDoc(title = "核销优惠券",
description = "物业手机版 或者第三方平台调用 核销功能核销优惠券",
httpMethod = "post",
url = "http://{ip}:{port}/app/couponProperty.writeOffCouponPropertyUser",
resource = "acctDoc",
author = "吴学文",
serviceCode = "couponProperty.writeOffCouponPropertyUser"
)
@Java110ParamsDoc(params = {
@Java110ParamDoc(name = "communityId", length = 30, remark = "项目ID"),
@Java110ParamDoc(name = "couponQrcode", length = 30, remark = "核销码"),
@Java110ParamDoc(name = "giftCount", type = "int", length = 11, remark = "核销数量"),
})
@Java110ResponseDoc(
params = {
@Java110ParamDoc(name = "code", type = "int", length = 11, defaultValue = "0", remark = "返回编号,0 成功 其他失败"),
@Java110ParamDoc(name = "msg", type = "String", length = 250, defaultValue = "成功", remark = "描述"),
}
)
@Java110ExampleDoc(
reqBody = "{\"couponQrcode\":\"70ff0d19c69e490b9e656795811037c5\",\"communityId\":\"2022112555490011\",\"giftCount\":1}",
resBody = "{\"code\":0,\"data\":[{\"businessKey\":\"302022083031660031\",\"communityId\":\"2022112555490011\",\"couponId\":\"102022112610570082\",\"couponName\":\"购物券\",\"createTime\":\"2022-11-27 15:22:18\",\"detailType\":\"1011\",\"page\":-1,\"records\":0,\"remark\":\"wuxw-18909715555核销\",\"row\":0,\"statusCd\":\"0\",\"tel\":\"18909711443\",\"total\":0,\"uoId\":\"112022112729340004\",\"userName\":\"吴学文\",\"value\":\"面值:10元;\"}],\"msg\":\"成功\",\"page\":0,\"records\":1,\"rows\":0,\"total\":1}"
)
/**
* 核销优惠券命令类
* 负责处理优惠券的核销业务逻辑,包括参数验证、优惠券状态检查、库存扣减和核销记录保存
*
* @author 吴学文
* @version 1.0
* @since 2022
*/
@Java110Cmd(serviceCode = "couponProperty.writeOffCouponPropertyUser")
public class WriteOffCouponPropertyUserCmd extends Cmd {
@Autowired
private ICouponPropertyUserV1InnerServiceSMO couponPropertyUserV1InnerServiceSMOImpl;
@Autowired
private ICouponPropertyUserDetailV1InnerServiceSMO couponPropertyUserDetailV1InnerServiceSMOImpl;
@Autowired
private IUserV1InnerServiceSMO userV1InnerServiceSMOImpl;
/**
* 验证请求参数和优惠券状态
* 检查必要参数是否存在,验证优惠券二维码有效性,检查优惠券状态和库存数量
*
* @param event 命令事件对象
* @param context 命令数据流上下文
* @param reqJson 请求参数JSON对象
* @throws CmdException 当参数验证失败或优惠券状态不满足条件时抛出异常
*/
@Override
public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException {
// 验证必要参数是否存在
Assert.hasKeyAndValue(reqJson, "communityId", "未包含项目");
Assert.hasKeyAndValue(reqJson, "couponQrcode", "未包含优惠券");
Assert.hasKeyAndValue(reqJson, "giftCount", "未包含核销数量");
// 通过二维码从缓存中获取优惠券ID
String couponId = CommonCache.getAndRemoveValue(reqJson.getString("couponQrcode"));
if(StringUtil.isEmpty(couponId)){
throw new CmdException("优惠券不存在");
}
reqJson.put("couponId", couponId);
// 查询优惠券信息
CouponPropertyUserDto couponPropertyUserDto = new CouponPropertyUserDto();
couponPropertyUserDto.setCouponId(reqJson.getString("couponId"));
couponPropertyUserDto.setState(CouponPropertyUserDto.STATE_WAIT); // 只查询待使用的优惠券
List<CouponPropertyUserDto> couponPropertyUserDtos = couponPropertyUserV1InnerServiceSMOImpl.queryCouponPropertyUsers(couponPropertyUserDto);
// 验证优惠券是否存在
if (couponPropertyUserDtos == null || couponPropertyUserDtos.size() < 1) {
throw new CmdException("优惠券不存在");
}
// 验证优惠券是否过期
if (!"Y".equals(couponPropertyUserDtos.get(0).getIsExpire())) {
throw new CmdException("优惠券已过期");
}
// 验证库存是否足够
int stock = Integer.parseInt(couponPropertyUserDtos.get(0).getStock());
int giftCount = Integer.parseInt(reqJson.getString("giftCount"));
if (stock < giftCount) {
throw new CmdException("优惠券不够赠送,当前数量为:" + stock);
}
}
/**
* 执行优惠券核销操作
* 使用分布式锁保证并发安全,更新优惠券库存,保存核销记录
*
* @param event 命令事件对象
* @param context 命令数据流上下文
* @param reqJson 请求参数JSON对象
* @throws CmdException 当核销操作失败时抛出异常
* @throws ParseException 当解析异常时抛出
*/
@Override
@Java110Transactional
public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException, ParseException {
// 获取分布式锁,防止并发操作
String requestId = DistributedLock.getLockUUID();
String key = this.getClass().getSimpleName() + reqJson.getString("couponId");
int flag = 0;
List<CouponPropertyUserDto> couponPropertyUserDtos = null;
try {
// 重新查询优惠券信息,确保数据一致性
CouponPropertyUserDto couponPropertyUserDto = new CouponPropertyUserDto();
couponPropertyUserDto.setCouponId(reqJson.getString("couponId"));
couponPropertyUserDto.setState(CouponPropertyUserDto.STATE_WAIT);
couponPropertyUserDtos = couponPropertyUserV1InnerServiceSMOImpl.queryCouponPropertyUsers(couponPropertyUserDto);
// 双重验证优惠券状态
if (couponPropertyUserDtos == null || couponPropertyUserDtos.size() < 1) {
throw new CmdException("优惠券不存在");
}
if (!"Y".equals(couponPropertyUserDtos.get(0).getIsExpire())) {
throw new CmdException("优惠券已过期");
}
int stock = Integer.parseInt(couponPropertyUserDtos.get(0).getStock());
int giftCount = Integer.parseInt(reqJson.getString("giftCount"));
if (stock < giftCount) {
throw new CmdException("优惠券不够赠送,当前数量为:" + stock);
}
// 更新优惠券库存信息
CouponPropertyUserPo couponPropertyUserPo = new CouponPropertyUserPo();
couponPropertyUserPo.setCouponId(couponPropertyUserDtos.get(0).getCouponId());
couponPropertyUserPo.setCommunityId(couponPropertyUserDtos.get(0).getCommunityId());
couponPropertyUserPo.setStock((stock - giftCount) + ""); // 扣减库存
// 如果库存扣减完毕,更新优惠券状态为已完成
if (stock == giftCount) {
couponPropertyUserPo.setState(CouponPropertyUserDto.STATE_FINISH);
}
flag = couponPropertyUserV1InnerServiceSMOImpl.updateCouponPropertyUser(couponPropertyUserPo);
if (flag < 1) {
throw new CmdException("赠送失败");
}
} finally {
// 释放分布式锁
DistributedLock.releaseDistributedLock(requestId, key);
}
// 保存核销记录
String userId = context.getReqHeaders().get("user-id");
String remark = getRemark(userId); // 获取核销备注信息
CouponPropertyUserDetailPo couponPropertyUserDetailPo = new CouponPropertyUserDetailPo();
couponPropertyUserDetailPo.setBusinessKey(StringUtil.isEmpty(userId)?"-1":userId); // 设置业务主键
couponPropertyUserDetailPo.setCommunityId(reqJson.getString("communityId"));
couponPropertyUserDetailPo.setCouponId(couponPropertyUserDtos.get(0).getCouponId());
couponPropertyUserDetailPo.setCouponName(couponPropertyUserDtos.get(0).getCouponName());
couponPropertyUserDetailPo.setUoId(GenerateCodeFactory.getGeneratorId("11")); // 生成唯一ID
couponPropertyUserDetailPo.setDetailType(couponPropertyUserDtos.get(0).getToType());
// 设置备注信息,优先使用请求中的备注
if(reqJson.containsKey("remark")) {
couponPropertyUserDetailPo.setRemark(remark + reqJson.getString("remark"));
}else{
couponPropertyUserDetailPo.setRemark(remark);
}
flag = couponPropertyUserDetailV1InnerServiceSMOImpl.saveCouponPropertyUserDetail(couponPropertyUserDetailPo);
if (flag < 1) {
throw new CmdException("赠送失败");
}
// 查询并返回核销记录详情
CouponPropertyUserDetailDto couponPropertyUserDetailDto = new CouponPropertyUserDetailDto();
couponPropertyUserDetailDto.setUoId(couponPropertyUserDetailPo.getUoId());
List<CouponPropertyUserDetailDto> couponPropertyUserDetailDtos
= couponPropertyUserDetailV1InnerServiceSMOImpl.queryCouponPropertyUserDetails(couponPropertyUserDetailDto);
context.setResponseEntity(ResultVo.createResponseEntity(couponPropertyUserDetailDtos));
}
/**
* 获取核销备注信息
* 根据用户ID查询用户信息,生成格式化的核销备注
*
* @param userId 用户ID
* @return 格式化后的核销备注信息
*/
private String getRemark(String userId) {
// 如果用户ID为空或者是默认值,返回接口核销标识
if(StringUtil.isEmpty(userId) || "-1".equals(userId)){
return "接口核销";
}
// 根据用户ID查询用户信息
UserDto userDto = new UserDto();
userDto.setUserId(userId);
List<UserDto> userDtos = userV1InnerServiceSMOImpl.queryUsers(userDto);
// 如果用户不存在,返回接口核销标识
if (userDtos == null || userDtos.size() < 1) {
return "接口核销";
}
// 返回格式化的核销备注:用户名-手机号核销
return userDtos.get(0).getName() + "-" + userDtos.get(0).getTel() + "核销";
}
}